FER Model Training

Table of Contents


Importing Libraries

In [1]:
! pip install scikeras
Collecting scikeras
  Downloading scikeras-0.7.0-py3-none-any.whl (27 kB)
Requirement already satisfied: scikit-learn>=1.0.0 in /usr/local/lib/python3.7/dist-packages (from scikeras) (1.0.2)
Requirement already satisfied: importlib-metadata>=3 in /usr/local/lib/python3.7/dist-packages (from scikeras) (4.11.3)
Requirement already satisfied: packaging<22.0,>=0.21 in /usr/local/lib/python3.7/dist-packages (from scikeras) (21.3)
Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=3->scikeras) (4.2.0)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=3->scikeras) (3.8.0)
Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /usr/local/lib/python3.7/dist-packages (from packaging<22.0,>=0.21->scikeras) (3.0.8)
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=1.0.0->scikeras) (3.1.0)
Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=1.0.0->scikeras) (1.1.0)
Requirement already satisfied: numpy>=1.14.6 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=1.0.0->scikeras) (1.21.6)
Requirement already satisfied: scipy>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=1.0.0->scikeras) (1.4.1)
Installing collected packages: scikeras
Successfully installed scikeras-0.7.0
In [3]:
import tensorflow as tf
import numpy as np
import random
import os
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

from tensorflow import keras
from tensorflow.keras import models, layers, optimizers, regularizers
from tensorflow.keras.utils import to_categorical, plot_model
from keras.preprocessing.image import ImageDataGenerator
from imblearn.over_sampling import RandomOverSampler
from sklearn.model_selection import train_test_split, GridSearchCV
from scikeras.wrappers import KerasClassifier
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, f1_score, classification_report
from prettytable import PrettyTable

Helper Functions

In [4]:
# helper function for loading the dataframe, oversampling and reshaping images, and assigning the data onto training labels
def load_fer_dataset(df) :
  width, height = 48, 48
  x_train, x_test = df['pixels'], df['emotion']
  oversampler = RandomOverSampler(sampling_strategy='auto') # oversampling dataset to fix the imbalance problem

  x_train, x_test = oversampler.fit_resample(x_train.values.reshape(-1,1), x_test)
  x_train = pd.Series(x_train.flatten())
  x_train = np.array(list(map(str.split, x_train)), 'float32') / 255
  x_train = x_train.reshape(-1, width, height, 1)

  x_test = np.array(x_test)
  x_test = x_test.reshape(x_test.shape[0], 1)

  return train_test_split(x_train, x_test, test_size=0.2, random_state=45) # 20% test data
In [5]:
def preprocess_labels(y_train, y_test, y_val, num_classes):
  return to_categorical(y_train, num_classes), to_categorical(y_test, num_classes), to_categorical(y_val, num_classes) # one hot encoding the training set, test set and validation set
In [6]:
# plotting 7 samples from each emotion classes
def plot_all_emotions():
  fig = plt.figure(1, (12, 12))
  fig.suptitle("Images representing each emotion", fontsize=20, weight='bold')
  img_count = 0

  for num_emotion in sorted(df_explore.emotion.unique()):
      for emotion in range(len(df_explore.emotion.unique())):      
          pixel = df_explore[df_explore.emotion == num_emotion].pixels.iloc[img_count]
          pixel = np.array(pixel.split(' ')).reshape(48, 48).astype('float32')
          img_count += 1

          axis = plt.subplot(len(df_explore.emotion.unique()),
                             len(df_explore.emotion.unique()),
                             img_count)
          axis.imshow(pixel, cmap='gray')
          axis.axis('off')
          axis.set_title(decoded_emotions[num_emotion], fontsize=12)
  return plt.show()
In [7]:
# plotting one sample belonging to a specific emotion class
def plot_one_emotion(emotion, location):
  pixel = df_explore[df_explore.emotion == emotion].pixels.iloc[location]
  pixel = np.array(pixel.split(' ')).reshape(48, 48).astype('float32')
  plt.title(decoded_emotions[emotion], fontsize=12, weight='bold')
  return plt.imshow(pixel, cmap='gray')
In [8]:
# plotting all samples of images that have been augmented
def plot_augmentation_samples(train_datagen):
  fig = plt.figure(figsize=(25, 10))
  fig.suptitle("Data Augmentation Samples", fontsize=20, weight='bold')
  rows = 3
  columns = 10
  iterator = train_datagen.flow(x_train, batch_size=64)

  for i in range(rows * columns):
    fig.add_subplot(rows, columns, i+1)
    plt.grid(False)
    batch = iterator.next()
    plt.imshow(np.squeeze(batch[0]), cmap=plt.cm.gray)
    plt.xticks([])
    plt.yticks([])
  save_figure("Data Augmentation Samples", tight_layout=False)
  plt.show()
In [9]:
# helper function for training the model i.e. running for epochs
def train_model(model, epoch, batch):  
  callbacks_list = [
                    EarlyStopping( # if the model doesn't improve its validation accuracy for up to 5 epochs, it will stop training
                        monitor='val_accuracy',
                        patience=3, # represents the number of epochs with no improvement to which the training will be terminated
                        verbose=1,
                        restore_best_weights=True
                        ),
                    ModelCheckpoint( # if the model reaches an optimal validation loss, it will be saved onto the directory so it can be loaded later
                        filepath='best-model.h5',
                        verbose=1,
                        monitor='val_loss',
                        save_best_only=True,
                        ),
                    ReduceLROnPlateau(
                        monitor='val_loss',
                        factor=np.sqrt(0.1),
                        patience=3,
                        verbose=1,
                        min_delta=0.0001
                        )
                    ]
                    
  return model.fit(x_train, 
                   y_train,
                   epochs = epoch,
                   batch_size = batch,
                   callbacks=callbacks_list,
                   validation_data = (x_val, y_val))
In [10]:
# helper function for retrieving a data augmentation generator
def get_augmented_generator(train_datagen, batch):
  return train_datagen.flow(x_train, y_train, batch_size=batch)
In [11]:
# helper function for training the model with the data augmentation generator
def train_augmented_model(model, train_datagen, epoch, batch):  
  callbacks_list = [
                    EarlyStopping( # if the model doesn't improve its validation accuracy for up to 5 epochs, it will stop training
                        monitor='val_accuracy',
                        patience=3, # represents the number of epochs with no improvement to which the training will be terminated
                        verbose=1,
                        restore_best_weights=True
                        ),
                    ModelCheckpoint( # if the model reaches an optimal validation loss, it will be saved onto the directory so it can be loaded later
                        filepath='best-model.h5',
                        verbose=1,
                        monitor='val_loss',
                        save_best_only=True,
                        ),
                    ReduceLROnPlateau(
                        monitor='val_loss',
                        factor=0.2,
                        patience=3,
                        verbose=1,
                        min_delta=0.0001
                        ),
                    ]

  return model.fit(get_augmented_generator(train_datagen, batch),
                   epochs = epoch,
                   steps_per_epoch = x_train.shape[0] // batch,
                   validation_data = (x_val, y_val),
                   callbacks=callbacks_list,
                   validation_steps = len(x_val) // batch)
In [12]:
# retrieves all history keys of the model
def get_history_keys(history):
  return (history.history,
          history.history["loss"],
          history.history["val_loss"], 
          history.history["accuracy"],
          history.history["val_accuracy"])

# plots both the model loss and accuracy
def plot_model_history(history, name=""):
  history_dict, loss, val_loss, acc, val_acc = get_history_keys(history) # get histories
  epochs = range(1, len(loss) + 1)
  blue_dots = 'bo'
  solid_blue_line = 'b'

  # defining the history subplots 
  values, axis = plt.subplots(1, 2)
  values.suptitle(name, fontsize=14)
  values.set_size_inches(14, 6)

  # plotting the values on the axis for each subplot
  axis[0].plot(epochs, loss, blue_dots, label = 'Training loss')
  axis[0].plot(epochs, val_loss, solid_blue_line, label = 'Validation loss')
  axis[1].plot(epochs, acc, blue_dots, label = 'Training acc')
  axis[1].plot(epochs, val_acc, solid_blue_line, label = 'Validation acc')

  # defining the labels
  plt.setp(axis[0], xlabel='Epochs')
  plt.setp(axis[0], ylabel='Loss')
  plt.setp(axis[1], xlabel='Epochs')
  plt.setp(axis[1], ylabel='Accuracy')
  axis[0].set_title('Training and validation loss')
  axis[0].legend()
  axis[1].set_title('Training and validation acc')
  axis[1].legend()

  # printing out minimum/maximum validation loss and accuracy
  print(f"\nMin validation loss: {str(min(val_loss))} \nMax validation loss: {str(max(val_loss))} \nMin validation acc: {str(min(val_acc))} \nMax validation acc: {str(max(val_acc))}")
In [13]:
# retrieves all history keys from the two models
def get_comparison_history_keys(history1, history2):
  return (history1.history,
          history2.history,
          history1.history["val_loss"], 
          history2.history["val_loss"], 
          history1.history["val_accuracy"],
          history2.history["val_accuracy"])


def compare_model_history(history1, history2, name="", key1="", key2=""):
  history_dict1, history_dict2, model_1_val_loss, model_2_val_loss, model_1_val_acc, model_2_val_acc = get_comparison_history_keys(history1, history2)
  epochs = range(1, len(model_1_val_loss) + 1)

  # defining the history subplots 
  values, axis = plt.subplots(1, 2)
  values.suptitle(name, fontsize=14)
  values.set_size_inches(14, 6)

  # plotting the values on the axis for each subplot
  axis[0].plot(epochs, model_1_val_loss, 'g', label = key1 + ' Loss')
  axis[0].plot(epochs, model_2_val_loss, 'b', label = key2 + ' Loss')
  axis[1].plot(epochs, model_1_val_acc, 'g', label = key1 + ' Accuracy')
  axis[1].plot(epochs, model_2_val_acc, 'b', label = key2 + ' Accuracy')

  # defining the labels
  plt.setp(axis[0], xlabel='Epochs')
  plt.setp(axis[0], ylabel='Loss')
  plt.setp(axis[1], xlabel='Epochs')
  plt.setp(axis[1], ylabel='Accuracy')
  axis[0].set_title('Validation Loss')
  axis[0].legend()
  axis[1].set_title('Validation Accuracy')
  axis[1].legend()

  # printing out minimum/maximum validation loss and accuracy for each model
  print(f"\n{key1} validation loss: {str(min(model_1_val_loss))} \n{key2} validation loss: {str(min(model_2_val_loss))}")
  print(f"\n{key1} validation accuracy: {str(max(model_1_val_acc))} \n{key2} validation accuracy: {str(max(model_2_val_acc))}")
In [14]:
# helper function to plot the grid search results
def plot_grid_search_results(results):
    print(f"\nBest score = {'%.2f' % results.best_score_} using {results.best_params_}\n")
    mean_score = results.cv_results_['mean_test_score']
    standard_deviation = results.cv_results_['std_test_score']
    parameters = results.cv_results_['params']
    optimised_model = grid_searcher_result.best_estimator_
    accuracy = optimised_model.score(x_test, y_test)

    for mean, stdev, param in zip(mean_score, standard_deviation, parameters):
        print('mean test accuracy +/- std = {:.4f} +/- {:.4f} with: {}'.format(mean, stdev, param))
    print("\nAccuracy achieved on the best model")
    print("{:.2f}%".format(accuracy * 100))
In [15]:
# helper function for saving the visualisations and images onto the directory
def save_figure(figure_name, tight_layout=True, fig_extension="png", resolution=300):
    path = os.path.join(".", figure_name + "." + fig_extension)
    print(figure_name, "has been saved")
    if tight_layout:
        plt.tight_layout()
    plt.savefig(path, format=fig_extension, dpi=resolution)

Loading and Inspecting the Data

In [18]:
df = pd.read_csv('/content/drive/MyDrive/Full-FER-2013-Dataset/fer2013.csv')
df.head()
Out[18]:
emotion pixels Usage
0 0 70 80 82 72 58 58 60 63 54 58 60 48 89 115 121... Training
1 0 151 150 147 155 148 133 111 140 170 174 182 15... Training
2 2 231 212 156 164 174 138 161 173 182 200 106 38... Training
3 4 24 32 36 30 32 23 19 20 30 41 21 22 32 34 21 1... Training
4 6 4 0 0 0 0 0 0 0 0 0 0 0 3 15 23 28 48 50 58 84... Training
In [ ]:
df.tail()
Out[ ]:
emotion pixels Usage
35882 6 50 36 17 22 23 29 33 39 34 37 37 37 39 43 48 5... PrivateTest
35883 3 178 174 172 173 181 188 191 194 196 199 200 20... PrivateTest
35884 0 17 17 16 23 28 22 19 17 25 26 20 24 31 19 27 9... PrivateTest
35885 3 30 28 28 29 31 30 42 68 79 81 77 67 67 71 63 6... PrivateTest
35886 2 19 13 14 12 13 16 21 33 50 57 71 84 97 108 122... PrivateTest
In [ ]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35887 entries, 0 to 35886
Data columns (total 3 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   emotion  35887 non-null  int64 
 1   pixels   35887 non-null  object
 2   Usage    35887 non-null  object
dtypes: int64(1), object(2)
memory usage: 841.2+ KB
In [ ]:
df.describe()
Out[ ]:
emotion
count 35887.000000
mean 3.323265
std 1.873819
min 0.000000
25% 2.000000
50% 3.000000
75% 5.000000
max 6.000000
In [ ]:
df['emotion'].value_counts()
Out[ ]:
3    8989
6    6198
4    6077
2    5121
0    4953
5    4002
1     547
Name: emotion, dtype: int64

Data Exploration

In [19]:
df_explore = df.copy()
df_explore.head()
Out[19]:
emotion pixels Usage
0 0 70 80 82 72 58 58 60 63 54 58 60 48 89 115 121... Training
1 0 151 150 147 155 148 133 111 140 170 174 182 15... Training
2 2 231 212 156 164 174 138 161 173 182 200 106 38... Training
3 4 24 32 36 30 32 23 19 20 30 41 21 22 32 34 21 1... Training
4 6 4 0 0 0 0 0 0 0 0 0 0 0 3 15 23 28 48 50 58 84... Training
In [20]:
decoded_emotions = {0:'Angry', 
                    1:'Disgusted', 
                    2:'Scared', 
                    3:'Happy', 
                    4: 'Sad', 
                    5: 'Suprised', 
                    6: 'Neutral'}

print("Distribution of samples per emotion:\n{}".format(df_explore.groupby("emotion").size()))
Distribution of samples per emotion:
emotion
0    4953
1     547
2    5121
3    8989
4    6077
5    4002
6    6198
dtype: int64
In [ ]:
df_explore['emotion'].isna().sum()
Out[ ]:
0
In [ ]:
df_explore['pixels'].isna().sum()
Out[ ]:
0
In [ ]:
df_explore['Usage'].isna().sum()
Out[ ]:
0
In [ ]:
df_explore.hist(bins=30, figsize=(10, 5), legend=True, color = (0.5,0.8,0.2,1))
plt.title('Visualisation of samples per emotion')
plt.xlabel('emotion')
plt.ylabel('count')
plt.xticks(np.array(list(decoded_emotions.keys())), decoded_emotions.values())

for i in range(len(df_explore["emotion"].value_counts())):
    plt.annotate(df_explore["emotion"].value_counts()[i], (i, df_explore["emotion"].value_counts()[i] + 50))

plt.tight_layout()
plt.show()
In [ ]:
plot_all_emotions()
In [ ]:
# plot_one_emotion(emotion=1, location=1) # specific location
emotion = 3 # select an emotion key
plot_one_emotion(emotion=emotion, location=random.randint(1, 100)) # random location
Out[ ]:
<matplotlib.image.AxesImage at 0x7f557488b250>

Preparing the Data for Training

In [21]:
# Training: 70
# Testing: 20
# Validation: 10
x_train, x_test, y_train, y_test = load_fer_dataset(df) # splitting the data into train/test
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.1, random_state=45) # creating a validation set

num_classes = len(decoded_emotions)
y_train, y_test, y_val = preprocess_labels(y_train, y_test, y_val, num_classes=num_classes) # preprocessing labels
In [22]:
len(df)
Out[22]:
35887
In [23]:
len(x_train) + len(x_test) + len(x_val) # after oversampling
Out[23]:
62923
In [24]:
len(x_train), len(x_test), len(x_val)
Out[24]:
(45304, 12585, 5034)

Initial Models for Training

CNN Model 1 - Simple Model

In [25]:
def model_1():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(32, kernel_size=3, strides=1, padding="valid", activation='relu', input_shape=(x_train.shape[1:])))

  # 2nd convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding="same", activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))

  # 3rd convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding="valid", activation='relu'))

  # 4th convolutional layer
  model.add(layers.Conv2D(128, kernel_size=3, strides=1, padding="same", activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))

  # 5th convolutional layer
  model.add(layers.Conv2D(128, kernel_size=3, strides=1, padding="valid", activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Flatten())

  # Dense layers
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [26]:
model = model_1()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[26]:
In [27]:
model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 46, 46, 32)        320       
                                                                 
 conv2d_1 (Conv2D)           (None, 46, 46, 64)        18496     
                                                                 
 max_pooling2d (MaxPooling2D  (None, 23, 23, 64)       0         
 )                                                               
                                                                 
 conv2d_2 (Conv2D)           (None, 21, 21, 64)        36928     
                                                                 
 conv2d_3 (Conv2D)           (None, 21, 21, 128)       73856     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 10, 10, 128)      0         
 2D)                                                             
                                                                 
 conv2d_4 (Conv2D)           (None, 8, 8, 128)         147584    
                                                                 
 max_pooling2d_2 (MaxPooling  (None, 4, 4, 128)        0         
 2D)                                                             
                                                                 
 flatten (Flatten)           (None, 2048)              0         
                                                                 
 dense (Dense)               (None, 256)               524544    
                                                                 
 dense_1 (Dense)             (None, 7)                 1799      
                                                                 
=================================================================
Total params: 803,527
Trainable params: 803,527
Non-trainable params: 0
_________________________________________________________________
In [ ]:
history1 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
708/708 [==============================] - ETA: 0s - loss: 1.7275 - accuracy: 0.3194
Epoch 1: val_loss improved from inf to 1.53934, saving model to best-model.h5
708/708 [==============================] - 14s 17ms/step - loss: 1.7275 - accuracy: 0.3194 - val_loss: 1.5393 - val_accuracy: 0.4182 - lr: 1.0000e-04
Epoch 2/30
705/708 [============================>.] - ETA: 0s - loss: 1.4399 - accuracy: 0.4635
Epoch 2: val_loss improved from 1.53934 to 1.35400, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 1.4396 - accuracy: 0.4635 - val_loss: 1.3540 - val_accuracy: 0.4960 - lr: 1.0000e-04
Epoch 3/30
708/708 [==============================] - ETA: 0s - loss: 1.2667 - accuracy: 0.5315
Epoch 3: val_loss improved from 1.35400 to 1.23979, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 1.2667 - accuracy: 0.5315 - val_loss: 1.2398 - val_accuracy: 0.5465 - lr: 1.0000e-04
Epoch 4/30
705/708 [============================>.] - ETA: 0s - loss: 1.1215 - accuracy: 0.5877
Epoch 4: val_loss improved from 1.23979 to 1.14390, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 1.1215 - accuracy: 0.5878 - val_loss: 1.1439 - val_accuracy: 0.5691 - lr: 1.0000e-04
Epoch 5/30
705/708 [============================>.] - ETA: 0s - loss: 1.0004 - accuracy: 0.6335
Epoch 5: val_loss improved from 1.14390 to 1.06031, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 1.0004 - accuracy: 0.6337 - val_loss: 1.0603 - val_accuracy: 0.6047 - lr: 1.0000e-04
Epoch 6/30
706/708 [============================>.] - ETA: 0s - loss: 0.8995 - accuracy: 0.6750
Epoch 6: val_loss improved from 1.06031 to 1.01505, saving model to best-model.h5
708/708 [==============================] - 12s 16ms/step - loss: 0.8993 - accuracy: 0.6752 - val_loss: 1.0151 - val_accuracy: 0.6317 - lr: 1.0000e-04
Epoch 7/30
705/708 [============================>.] - ETA: 0s - loss: 0.8081 - accuracy: 0.7098
Epoch 7: val_loss improved from 1.01505 to 0.96490, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 0.8081 - accuracy: 0.7099 - val_loss: 0.9649 - val_accuracy: 0.6599 - lr: 1.0000e-04
Epoch 8/30
705/708 [============================>.] - ETA: 0s - loss: 0.7232 - accuracy: 0.7448
Epoch 8: val_loss improved from 0.96490 to 0.94204, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 0.7231 - accuracy: 0.7448 - val_loss: 0.9420 - val_accuracy: 0.6762 - lr: 1.0000e-04
Epoch 9/30
708/708 [==============================] - ETA: 0s - loss: 0.6458 - accuracy: 0.7729
Epoch 9: val_loss did not improve from 0.94204
708/708 [==============================] - 11s 16ms/step - loss: 0.6458 - accuracy: 0.7729 - val_loss: 0.9766 - val_accuracy: 0.6754 - lr: 1.0000e-04
Epoch 10/30
705/708 [============================>.] - ETA: 0s - loss: 0.5687 - accuracy: 0.8032
Epoch 10: val_loss improved from 0.94204 to 0.92767, saving model to best-model.h5
708/708 [==============================] - 11s 16ms/step - loss: 0.5687 - accuracy: 0.8033 - val_loss: 0.9277 - val_accuracy: 0.6935 - lr: 1.0000e-04
Epoch 11/30
708/708 [==============================] - ETA: 0s - loss: 0.5030 - accuracy: 0.8286
Epoch 11: val_loss did not improve from 0.92767
708/708 [==============================] - 11s 16ms/step - loss: 0.5030 - accuracy: 0.8286 - val_loss: 0.9493 - val_accuracy: 0.7000 - lr: 1.0000e-04
Epoch 12/30
705/708 [============================>.] - ETA: 0s - loss: 0.4361 - accuracy: 0.8530
Epoch 12: val_loss improved from 0.92767 to 0.91674, saving model to best-model.h5
708/708 [==============================] - 12s 16ms/step - loss: 0.4360 - accuracy: 0.8531 - val_loss: 0.9167 - val_accuracy: 0.7275 - lr: 1.0000e-04
Epoch 13/30
705/708 [============================>.] - ETA: 0s - loss: 0.3751 - accuracy: 0.8756
Epoch 13: val_loss did not improve from 0.91674
708/708 [==============================] - 11s 16ms/step - loss: 0.3749 - accuracy: 0.8757 - val_loss: 0.9382 - val_accuracy: 0.7372 - lr: 1.0000e-04
Epoch 14/30
706/708 [============================>.] - ETA: 0s - loss: 0.3237 - accuracy: 0.8936
Epoch 14: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.3238 - accuracy: 0.8936 - val_loss: 0.9720 - val_accuracy: 0.7418 - lr: 1.0000e-04
Epoch 15/30
705/708 [============================>.] - ETA: 0s - loss: 0.2755 - accuracy: 0.9089
Epoch 15: val_loss did not improve from 0.91674

Epoch 15: ReduceLROnPlateau reducing learning rate to 3.1622775802825264e-05.
708/708 [==============================] - 12s 16ms/step - loss: 0.2758 - accuracy: 0.9088 - val_loss: 1.0477 - val_accuracy: 0.7390 - lr: 1.0000e-04
Epoch 16/30
708/708 [==============================] - ETA: 0s - loss: 0.1583 - accuracy: 0.9560
Epoch 16: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.1583 - accuracy: 0.9560 - val_loss: 1.0132 - val_accuracy: 0.7680 - lr: 3.1623e-05
Epoch 17/30
705/708 [============================>.] - ETA: 0s - loss: 0.1326 - accuracy: 0.9642
Epoch 17: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.1325 - accuracy: 0.9642 - val_loss: 1.0862 - val_accuracy: 0.7721 - lr: 3.1623e-05
Epoch 18/30
705/708 [============================>.] - ETA: 0s - loss: 0.1169 - accuracy: 0.9687
Epoch 18: val_loss did not improve from 0.91674

Epoch 18: ReduceLROnPlateau reducing learning rate to 9.999999259090306e-06.
708/708 [==============================] - 12s 16ms/step - loss: 0.1168 - accuracy: 0.9687 - val_loss: 1.1077 - val_accuracy: 0.7769 - lr: 3.1623e-05
Epoch 19/30
705/708 [============================>.] - ETA: 0s - loss: 0.0834 - accuracy: 0.9814
Epoch 19: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0835 - accuracy: 0.9813 - val_loss: 1.1352 - val_accuracy: 0.7827 - lr: 1.0000e-05
Epoch 20/30
708/708 [==============================] - ETA: 0s - loss: 0.0760 - accuracy: 0.9839
Epoch 20: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0760 - accuracy: 0.9839 - val_loss: 1.1543 - val_accuracy: 0.7835 - lr: 1.0000e-05
Epoch 21/30
705/708 [============================>.] - ETA: 0s - loss: 0.0712 - accuracy: 0.9850
Epoch 21: val_loss did not improve from 0.91674

Epoch 21: ReduceLROnPlateau reducing learning rate to 3.162277292675049e-06.
708/708 [==============================] - 12s 16ms/step - loss: 0.0711 - accuracy: 0.9850 - val_loss: 1.1847 - val_accuracy: 0.7839 - lr: 1.0000e-05
Epoch 22/30
705/708 [============================>.] - ETA: 0s - loss: 0.0613 - accuracy: 0.9885
Epoch 22: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0612 - accuracy: 0.9885 - val_loss: 1.1821 - val_accuracy: 0.7872 - lr: 3.1623e-06
Epoch 23/30
708/708 [==============================] - ETA: 0s - loss: 0.0591 - accuracy: 0.9893
Epoch 23: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0591 - accuracy: 0.9893 - val_loss: 1.1973 - val_accuracy: 0.7878 - lr: 3.1623e-06
Epoch 24/30
705/708 [============================>.] - ETA: 0s - loss: 0.0571 - accuracy: 0.9895
Epoch 24: val_loss did not improve from 0.91674

Epoch 24: ReduceLROnPlateau reducing learning rate to 9.999999115286567e-07.
708/708 [==============================] - 12s 16ms/step - loss: 0.0572 - accuracy: 0.9895 - val_loss: 1.2062 - val_accuracy: 0.7886 - lr: 3.1623e-06
Epoch 25/30
705/708 [============================>.] - ETA: 0s - loss: 0.0541 - accuracy: 0.9907
Epoch 25: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0540 - accuracy: 0.9907 - val_loss: 1.2078 - val_accuracy: 0.7890 - lr: 1.0000e-06
Epoch 26/30
705/708 [============================>.] - ETA: 0s - loss: 0.0533 - accuracy: 0.9909
Epoch 26: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0533 - accuracy: 0.9909 - val_loss: 1.2100 - val_accuracy: 0.7896 - lr: 1.0000e-06
Epoch 27/30
708/708 [==============================] - ETA: 0s - loss: 0.0528 - accuracy: 0.9912
Epoch 27: val_loss did not improve from 0.91674

Epoch 27: ReduceLROnPlateau reducing learning rate to 3.1622772926750485e-07.
708/708 [==============================] - 12s 16ms/step - loss: 0.0528 - accuracy: 0.9912 - val_loss: 1.2148 - val_accuracy: 0.7878 - lr: 1.0000e-06
Epoch 28/30
705/708 [============================>.] - ETA: 0s - loss: 0.0518 - accuracy: 0.9914
Epoch 28: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0517 - accuracy: 0.9915 - val_loss: 1.2148 - val_accuracy: 0.7904 - lr: 3.1623e-07
Epoch 29/30
705/708 [============================>.] - ETA: 0s - loss: 0.0515 - accuracy: 0.9914
Epoch 29: val_loss did not improve from 0.91674
708/708 [==============================] - 12s 16ms/step - loss: 0.0515 - accuracy: 0.9914 - val_loss: 1.2161 - val_accuracy: 0.7898 - lr: 3.1623e-07
Epoch 30/30
708/708 [==============================] - ETA: 0s - loss: 0.0513 - accuracy: 0.9916
Epoch 30: val_loss did not improve from 0.91674

Epoch 30: ReduceLROnPlateau reducing learning rate to 9.99999875577722e-08.
708/708 [==============================] - 12s 16ms/step - loss: 0.0513 - accuracy: 0.9916 - val_loss: 1.2175 - val_accuracy: 0.7902 - lr: 3.1623e-07
394/394 [==============================] - 2s 4ms/step - loss: 1.1413 - accuracy: 0.8024
Out[ ]:
[1.1412922143936157, 0.8023837804794312]

CNN Model 2 - Upscaled and Regularised Model

In [28]:
def model_2():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [29]:
model = model_2()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[29]:
In [30]:
model.summary()
Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_5 (Conv2D)           (None, 48, 48, 64)        640       
                                                                 
 batch_normalization (BatchN  (None, 48, 48, 64)       256       
 ormalization)                                                   
                                                                 
 max_pooling2d_3 (MaxPooling  (None, 24, 24, 64)       0         
 2D)                                                             
                                                                 
 dropout (Dropout)           (None, 24, 24, 64)        0         
                                                                 
 conv2d_6 (Conv2D)           (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_1 (Batc  (None, 24, 24, 128)      512       
 hNormalization)                                                 
                                                                 
 max_pooling2d_4 (MaxPooling  (None, 12, 12, 128)      0         
 2D)                                                             
                                                                 
 dropout_1 (Dropout)         (None, 12, 12, 128)       0         
                                                                 
 conv2d_7 (Conv2D)           (None, 12, 12, 512)       590336    
                                                                 
 batch_normalization_2 (Batc  (None, 12, 12, 512)      2048      
 hNormalization)                                                 
                                                                 
 max_pooling2d_5 (MaxPooling  (None, 6, 6, 512)        0         
 2D)                                                             
                                                                 
 dropout_2 (Dropout)         (None, 6, 6, 512)         0         
                                                                 
 conv2d_8 (Conv2D)           (None, 6, 6, 512)         2359808   
                                                                 
 batch_normalization_3 (Batc  (None, 6, 6, 512)        2048      
 hNormalization)                                                 
                                                                 
 max_pooling2d_6 (MaxPooling  (None, 3, 3, 512)        0         
 2D)                                                             
                                                                 
 dropout_3 (Dropout)         (None, 3, 3, 512)         0         
                                                                 
 flatten_1 (Flatten)         (None, 4608)              0         
                                                                 
 dense_2 (Dense)             (None, 256)               1179904   
                                                                 
 batch_normalization_4 (Batc  (None, 256)              1024      
 hNormalization)                                                 
                                                                 
 dropout_4 (Dropout)         (None, 256)               0         
                                                                 
 dense_3 (Dense)             (None, 512)               131584    
                                                                 
 batch_normalization_5 (Batc  (None, 512)              2048      
 hNormalization)                                                 
                                                                 
 dropout_5 (Dropout)         (None, 512)               0         
                                                                 
 dense_4 (Dense)             (None, 7)                 3591      
                                                                 
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history2 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
708/708 [==============================] - ETA: 0s - loss: 2.2622 - accuracy: 0.2163
Epoch 1: val_loss improved from inf to 2.00889, saving model to best-model.h5
708/708 [==============================] - 31s 28ms/step - loss: 2.2622 - accuracy: 0.2163 - val_loss: 2.0089 - val_accuracy: 0.2437 - lr: 1.0000e-04
Epoch 2/30
707/708 [============================>.] - ETA: 0s - loss: 1.9367 - accuracy: 0.2967
Epoch 2: val_loss improved from 2.00889 to 1.71000, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.9364 - accuracy: 0.2968 - val_loss: 1.7100 - val_accuracy: 0.3607 - lr: 1.0000e-04
Epoch 3/30
706/708 [============================>.] - ETA: 0s - loss: 1.7139 - accuracy: 0.3693
Epoch 3: val_loss improved from 1.71000 to 1.55323, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.7135 - accuracy: 0.3695 - val_loss: 1.5532 - val_accuracy: 0.4261 - lr: 1.0000e-04
Epoch 4/30
706/708 [============================>.] - ETA: 0s - loss: 1.5288 - accuracy: 0.4328
Epoch 4: val_loss improved from 1.55323 to 1.46643, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.5285 - accuracy: 0.4329 - val_loss: 1.4664 - val_accuracy: 0.4740 - lr: 1.0000e-04
Epoch 5/30
706/708 [============================>.] - ETA: 0s - loss: 1.3797 - accuracy: 0.4872
Epoch 5: val_loss improved from 1.46643 to 1.25800, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.3790 - accuracy: 0.4874 - val_loss: 1.2580 - val_accuracy: 0.5358 - lr: 1.0000e-04
Epoch 6/30
706/708 [============================>.] - ETA: 0s - loss: 1.2607 - accuracy: 0.5279
Epoch 6: val_loss improved from 1.25800 to 1.14641, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.2610 - accuracy: 0.5278 - val_loss: 1.1464 - val_accuracy: 0.5723 - lr: 1.0000e-04
Epoch 7/30
707/708 [============================>.] - ETA: 0s - loss: 1.1533 - accuracy: 0.5676
Epoch 7: val_loss improved from 1.14641 to 1.04183, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.1532 - accuracy: 0.5676 - val_loss: 1.0418 - val_accuracy: 0.6118 - lr: 1.0000e-04
Epoch 8/30
707/708 [============================>.] - ETA: 0s - loss: 1.0698 - accuracy: 0.6001
Epoch 8: val_loss improved from 1.04183 to 0.99490, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.0694 - accuracy: 0.6003 - val_loss: 0.9949 - val_accuracy: 0.6315 - lr: 1.0000e-04
Epoch 9/30
707/708 [============================>.] - ETA: 0s - loss: 1.0035 - accuracy: 0.6231
Epoch 9: val_loss improved from 0.99490 to 0.94240, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.0035 - accuracy: 0.6231 - val_loss: 0.9424 - val_accuracy: 0.6496 - lr: 1.0000e-04
Epoch 10/30
707/708 [============================>.] - ETA: 0s - loss: 0.9376 - accuracy: 0.6474
Epoch 10: val_loss improved from 0.94240 to 0.90611, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.9374 - accuracy: 0.6475 - val_loss: 0.9061 - val_accuracy: 0.6649 - lr: 1.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.8783 - accuracy: 0.6721
Epoch 11: val_loss improved from 0.90611 to 0.83498, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.8784 - accuracy: 0.6720 - val_loss: 0.8350 - val_accuracy: 0.6915 - lr: 1.0000e-04
Epoch 12/30
707/708 [============================>.] - ETA: 0s - loss: 0.8190 - accuracy: 0.6976
Epoch 12: val_loss improved from 0.83498 to 0.79002, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.8188 - accuracy: 0.6977 - val_loss: 0.7900 - val_accuracy: 0.7082 - lr: 1.0000e-04
Epoch 13/30
706/708 [============================>.] - ETA: 0s - loss: 0.7533 - accuracy: 0.7223
Epoch 13: val_loss improved from 0.79002 to 0.77463, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.7527 - accuracy: 0.7225 - val_loss: 0.7746 - val_accuracy: 0.7245 - lr: 1.0000e-04
Epoch 14/30
706/708 [============================>.] - ETA: 0s - loss: 0.7026 - accuracy: 0.7409
Epoch 14: val_loss improved from 0.77463 to 0.73334, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.7026 - accuracy: 0.7410 - val_loss: 0.7333 - val_accuracy: 0.7402 - lr: 1.0000e-04
Epoch 15/30
707/708 [============================>.] - ETA: 0s - loss: 0.6465 - accuracy: 0.7630
Epoch 15: val_loss improved from 0.73334 to 0.68552, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 0.6463 - accuracy: 0.7632 - val_loss: 0.6855 - val_accuracy: 0.7612 - lr: 1.0000e-04
Epoch 16/30
707/708 [============================>.] - ETA: 0s - loss: 0.5960 - accuracy: 0.7830
Epoch 16: val_loss improved from 0.68552 to 0.66259, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5964 - accuracy: 0.7828 - val_loss: 0.6626 - val_accuracy: 0.7727 - lr: 1.0000e-04
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.5496 - accuracy: 0.8021
Epoch 17: val_loss improved from 0.66259 to 0.64119, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5498 - accuracy: 0.8021 - val_loss: 0.6412 - val_accuracy: 0.7868 - lr: 1.0000e-04
Epoch 18/30
707/708 [============================>.] - ETA: 0s - loss: 0.5069 - accuracy: 0.8181
Epoch 18: val_loss improved from 0.64119 to 0.61912, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5068 - accuracy: 0.8182 - val_loss: 0.6191 - val_accuracy: 0.7942 - lr: 1.0000e-04
Epoch 19/30
707/708 [============================>.] - ETA: 0s - loss: 0.4644 - accuracy: 0.8329
Epoch 19: val_loss improved from 0.61912 to 0.61613, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.4644 - accuracy: 0.8329 - val_loss: 0.6161 - val_accuracy: 0.8023 - lr: 1.0000e-04
Epoch 20/30
708/708 [==============================] - ETA: 0s - loss: 0.4249 - accuracy: 0.8490
Epoch 20: val_loss improved from 0.61613 to 0.60232, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.4249 - accuracy: 0.8490 - val_loss: 0.6023 - val_accuracy: 0.8111 - lr: 1.0000e-04
Epoch 21/30
706/708 [============================>.] - ETA: 0s - loss: 0.3885 - accuracy: 0.8610
Epoch 21: val_loss improved from 0.60232 to 0.59095, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.3887 - accuracy: 0.8610 - val_loss: 0.5910 - val_accuracy: 0.8224 - lr: 1.0000e-04
Epoch 22/30
707/708 [============================>.] - ETA: 0s - loss: 0.3618 - accuracy: 0.8720
Epoch 22: val_loss did not improve from 0.59095
708/708 [==============================] - 19s 26ms/step - loss: 0.3618 - accuracy: 0.8720 - val_loss: 0.5977 - val_accuracy: 0.8254 - lr: 1.0000e-04
Epoch 23/30
707/708 [============================>.] - ETA: 0s - loss: 0.3344 - accuracy: 0.8808
Epoch 23: val_loss did not improve from 0.59095
708/708 [==============================] - 19s 26ms/step - loss: 0.3348 - accuracy: 0.8807 - val_loss: 0.5999 - val_accuracy: 0.8210 - lr: 1.0000e-04
Epoch 24/30
707/708 [============================>.] - ETA: 0s - loss: 0.3067 - accuracy: 0.8908
Epoch 24: val_loss did not improve from 0.59095

Epoch 24: ReduceLROnPlateau reducing learning rate to 3.1622775802825264e-05.
708/708 [==============================] - 19s 26ms/step - loss: 0.3067 - accuracy: 0.8908 - val_loss: 0.6152 - val_accuracy: 0.8345 - lr: 1.0000e-04
Epoch 25/30
707/708 [============================>.] - ETA: 0s - loss: 0.2517 - accuracy: 0.9106
Epoch 25: val_loss improved from 0.59095 to 0.58899, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.2517 - accuracy: 0.9106 - val_loss: 0.5890 - val_accuracy: 0.8375 - lr: 3.1623e-05
Epoch 26/30
707/708 [============================>.] - ETA: 0s - loss: 0.2240 - accuracy: 0.9222
Epoch 26: val_loss did not improve from 0.58899
708/708 [==============================] - 19s 26ms/step - loss: 0.2241 - accuracy: 0.9222 - val_loss: 0.5913 - val_accuracy: 0.8413 - lr: 3.1623e-05
Epoch 27/30
707/708 [============================>.] - ETA: 0s - loss: 0.2101 - accuracy: 0.9264
Epoch 27: val_loss did not improve from 0.58899
708/708 [==============================] - 19s 27ms/step - loss: 0.2102 - accuracy: 0.9263 - val_loss: 0.5945 - val_accuracy: 0.8458 - lr: 3.1623e-05
Epoch 28/30
707/708 [============================>.] - ETA: 0s - loss: 0.1973 - accuracy: 0.9309
Epoch 28: val_loss did not improve from 0.58899

Epoch 28: ReduceLROnPlateau reducing learning rate to 9.999999259090306e-06.
708/708 [==============================] - 19s 27ms/step - loss: 0.1973 - accuracy: 0.9309 - val_loss: 0.5969 - val_accuracy: 0.8423 - lr: 3.1623e-05
Epoch 29/30
706/708 [============================>.] - ETA: 0s - loss: 0.1821 - accuracy: 0.9349
Epoch 29: val_loss did not improve from 0.58899
708/708 [==============================] - 19s 26ms/step - loss: 0.1821 - accuracy: 0.9349 - val_loss: 0.6006 - val_accuracy: 0.8403 - lr: 1.0000e-05
Epoch 30/30
707/708 [============================>.] - ETA: 0s - loss: 0.1734 - accuracy: 0.9398Restoring model weights from the end of the best epoch: 27.

Epoch 30: val_loss did not improve from 0.58899
708/708 [==============================] - 19s 27ms/step - loss: 0.1736 - accuracy: 0.9398 - val_loss: 0.5989 - val_accuracy: 0.8423 - lr: 1.0000e-05
Epoch 30: early stopping
394/394 [==============================] - 3s 6ms/step - loss: 0.6234 - accuracy: 0.8416
Out[ ]:
[0.6234413385391235, 0.8416368961334229]

CNN Model 2 with Leaky ReLu

In [31]:
def model_3():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation=tf.keras.layers.LeakyReLU(), input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation=tf.keras.layers.LeakyReLU()))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation=tf.keras.layers.LeakyReLU()))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation=tf.keras.layers.LeakyReLU()))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation=tf.keras.layers.LeakyReLU()))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation=tf.keras.layers.LeakyReLU()))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [32]:
model = model_3()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[32]:
In [33]:
model.summary()
Model: "sequential_2"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_9 (Conv2D)           (None, 48, 48, 64)        640       
                                                                 
 batch_normalization_6 (Batc  (None, 48, 48, 64)       256       
 hNormalization)                                                 
                                                                 
 max_pooling2d_7 (MaxPooling  (None, 24, 24, 64)       0         
 2D)                                                             
                                                                 
 dropout_6 (Dropout)         (None, 24, 24, 64)        0         
                                                                 
 conv2d_10 (Conv2D)          (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_7 (Batc  (None, 24, 24, 128)      512       
 hNormalization)                                                 
                                                                 
 max_pooling2d_8 (MaxPooling  (None, 12, 12, 128)      0         
 2D)                                                             
                                                                 
 dropout_7 (Dropout)         (None, 12, 12, 128)       0         
                                                                 
 conv2d_11 (Conv2D)          (None, 12, 12, 512)       590336    
                                                                 
 batch_normalization_8 (Batc  (None, 12, 12, 512)      2048      
 hNormalization)                                                 
                                                                 
 max_pooling2d_9 (MaxPooling  (None, 6, 6, 512)        0         
 2D)                                                             
                                                                 
 dropout_8 (Dropout)         (None, 6, 6, 512)         0         
                                                                 
 conv2d_12 (Conv2D)          (None, 6, 6, 512)         2359808   
                                                                 
 batch_normalization_9 (Batc  (None, 6, 6, 512)        2048      
 hNormalization)                                                 
                                                                 
 max_pooling2d_10 (MaxPoolin  (None, 3, 3, 512)        0         
 g2D)                                                            
                                                                 
 dropout_9 (Dropout)         (None, 3, 3, 512)         0         
                                                                 
 flatten_2 (Flatten)         (None, 4608)              0         
                                                                 
 dense_5 (Dense)             (None, 256)               1179904   
                                                                 
 batch_normalization_10 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_10 (Dropout)        (None, 256)               0         
                                                                 
 dense_6 (Dense)             (None, 512)               131584    
                                                                 
 batch_normalization_11 (Bat  (None, 512)              2048      
 chNormalization)                                                
                                                                 
 dropout_11 (Dropout)        (None, 512)               0         
                                                                 
 dense_7 (Dense)             (None, 7)                 3591      
                                                                 
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history3 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
708/708 [==============================] - ETA: 0s - loss: 2.1218 - accuracy: 0.2501
Epoch 1: val_loss improved from inf to 1.83007, saving model to best-model.h5
708/708 [==============================] - 31s 28ms/step - loss: 2.1218 - accuracy: 0.2501 - val_loss: 1.8301 - val_accuracy: 0.3192 - lr: 1.0000e-04
Epoch 2/30
707/708 [============================>.] - ETA: 0s - loss: 1.7720 - accuracy: 0.3515
Epoch 2: val_loss improved from 1.83007 to 1.65118, saving model to best-model.h5
708/708 [==============================] - 20s 29ms/step - loss: 1.7718 - accuracy: 0.3514 - val_loss: 1.6512 - val_accuracy: 0.3977 - lr: 1.0000e-04
Epoch 3/30
707/708 [============================>.] - ETA: 0s - loss: 1.5677 - accuracy: 0.4252
Epoch 3: val_loss improved from 1.65118 to 1.31767, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.5678 - accuracy: 0.4252 - val_loss: 1.3177 - val_accuracy: 0.5079 - lr: 1.0000e-04
Epoch 4/30
708/708 [==============================] - ETA: 0s - loss: 1.4088 - accuracy: 0.4773
Epoch 4: val_loss improved from 1.31767 to 1.27712, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.4088 - accuracy: 0.4773 - val_loss: 1.2771 - val_accuracy: 0.5282 - lr: 1.0000e-04
Epoch 5/30
707/708 [============================>.] - ETA: 0s - loss: 1.2937 - accuracy: 0.5212
Epoch 5: val_loss improved from 1.27712 to 1.19354, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.2935 - accuracy: 0.5213 - val_loss: 1.1935 - val_accuracy: 0.5556 - lr: 1.0000e-04
Epoch 6/30
707/708 [============================>.] - ETA: 0s - loss: 1.1957 - accuracy: 0.5550
Epoch 6: val_loss improved from 1.19354 to 1.08240, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 1.1956 - accuracy: 0.5550 - val_loss: 1.0824 - val_accuracy: 0.5999 - lr: 1.0000e-04
Epoch 7/30
707/708 [============================>.] - ETA: 0s - loss: 1.1103 - accuracy: 0.5875
Epoch 7: val_loss improved from 1.08240 to 1.01645, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 1.1101 - accuracy: 0.5876 - val_loss: 1.0165 - val_accuracy: 0.6307 - lr: 1.0000e-04
Epoch 8/30
707/708 [============================>.] - ETA: 0s - loss: 1.0421 - accuracy: 0.6109
Epoch 8: val_loss improved from 1.01645 to 0.95606, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 1.0422 - accuracy: 0.6109 - val_loss: 0.9561 - val_accuracy: 0.6395 - lr: 1.0000e-04
Epoch 9/30
707/708 [============================>.] - ETA: 0s - loss: 0.9763 - accuracy: 0.6356
Epoch 9: val_loss improved from 0.95606 to 0.90434, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.9765 - accuracy: 0.6355 - val_loss: 0.9043 - val_accuracy: 0.6669 - lr: 1.0000e-04
Epoch 10/30
707/708 [============================>.] - ETA: 0s - loss: 0.9133 - accuracy: 0.6594
Epoch 10: val_loss improved from 0.90434 to 0.87893, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 0.9131 - accuracy: 0.6595 - val_loss: 0.8789 - val_accuracy: 0.6756 - lr: 1.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.8608 - accuracy: 0.6811
Epoch 11: val_loss improved from 0.87893 to 0.83538, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 0.8609 - accuracy: 0.6810 - val_loss: 0.8354 - val_accuracy: 0.6953 - lr: 1.0000e-04
Epoch 12/30
707/708 [============================>.] - ETA: 0s - loss: 0.8075 - accuracy: 0.7013
Epoch 12: val_loss improved from 0.83538 to 0.83097, saving model to best-model.h5
708/708 [==============================] - 19s 28ms/step - loss: 0.8076 - accuracy: 0.7012 - val_loss: 0.8310 - val_accuracy: 0.7050 - lr: 1.0000e-04
Epoch 13/30
707/708 [============================>.] - ETA: 0s - loss: 0.7508 - accuracy: 0.7258
Epoch 13: val_loss improved from 0.83097 to 0.75781, saving model to best-model.h5
708/708 [==============================] - 20s 28ms/step - loss: 0.7508 - accuracy: 0.7258 - val_loss: 0.7578 - val_accuracy: 0.7318 - lr: 1.0000e-04
Epoch 14/30
707/708 [============================>.] - ETA: 0s - loss: 0.7057 - accuracy: 0.7425
Epoch 14: val_loss did not improve from 0.75781
708/708 [==============================] - 19s 27ms/step - loss: 0.7055 - accuracy: 0.7425 - val_loss: 0.7698 - val_accuracy: 0.7288 - lr: 1.0000e-04
Epoch 15/30
707/708 [============================>.] - ETA: 0s - loss: 0.6581 - accuracy: 0.7579
Epoch 15: val_loss improved from 0.75781 to 0.70808, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.6579 - accuracy: 0.7580 - val_loss: 0.7081 - val_accuracy: 0.7582 - lr: 1.0000e-04
Epoch 16/30
707/708 [============================>.] - ETA: 0s - loss: 0.6108 - accuracy: 0.7788
Epoch 16: val_loss did not improve from 0.70808
708/708 [==============================] - 19s 27ms/step - loss: 0.6109 - accuracy: 0.7786 - val_loss: 0.7470 - val_accuracy: 0.7481 - lr: 1.0000e-04
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.5711 - accuracy: 0.7948
Epoch 17: val_loss improved from 0.70808 to 0.70717, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5714 - accuracy: 0.7947 - val_loss: 0.7072 - val_accuracy: 0.7642 - lr: 1.0000e-04
Epoch 18/30
707/708 [============================>.] - ETA: 0s - loss: 0.5330 - accuracy: 0.8055
Epoch 18: val_loss improved from 0.70717 to 0.66166, saving model to best-model.h5
708/708 [==============================] - 19s 28ms/step - loss: 0.5333 - accuracy: 0.8054 - val_loss: 0.6617 - val_accuracy: 0.7872 - lr: 1.0000e-04
Epoch 19/30
707/708 [============================>.] - ETA: 0s - loss: 0.4945 - accuracy: 0.8224
Epoch 19: val_loss did not improve from 0.66166
708/708 [==============================] - 19s 27ms/step - loss: 0.4946 - accuracy: 0.8224 - val_loss: 0.6820 - val_accuracy: 0.7863 - lr: 1.0000e-04
Epoch 20/30
707/708 [============================>.] - ETA: 0s - loss: 0.4651 - accuracy: 0.8329
Epoch 20: val_loss did not improve from 0.66166
708/708 [==============================] - 19s 27ms/step - loss: 0.4649 - accuracy: 0.8330 - val_loss: 0.6723 - val_accuracy: 0.7926 - lr: 1.0000e-04
Epoch 21/30
708/708 [==============================] - ETA: 0s - loss: 0.4408 - accuracy: 0.8440
Epoch 21: val_loss improved from 0.66166 to 0.65541, saving model to best-model.h5
708/708 [==============================] - 19s 28ms/step - loss: 0.4408 - accuracy: 0.8440 - val_loss: 0.6554 - val_accuracy: 0.8012 - lr: 1.0000e-04
Epoch 22/30
707/708 [============================>.] - ETA: 0s - loss: 0.4069 - accuracy: 0.8554
Epoch 22: val_loss did not improve from 0.65541
708/708 [==============================] - 19s 27ms/step - loss: 0.4069 - accuracy: 0.8554 - val_loss: 0.6766 - val_accuracy: 0.7996 - lr: 1.0000e-04
Epoch 23/30
707/708 [============================>.] - ETA: 0s - loss: 0.3727 - accuracy: 0.8666
Epoch 23: val_loss improved from 0.65541 to 0.63402, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.3725 - accuracy: 0.8667 - val_loss: 0.6340 - val_accuracy: 0.8125 - lr: 1.0000e-04
Epoch 24/30
707/708 [============================>.] - ETA: 0s - loss: 0.3521 - accuracy: 0.8752
Epoch 24: val_loss did not improve from 0.63402
708/708 [==============================] - 19s 27ms/step - loss: 0.3522 - accuracy: 0.8752 - val_loss: 0.6514 - val_accuracy: 0.8113 - lr: 1.0000e-04
Epoch 25/30
707/708 [============================>.] - ETA: 0s - loss: 0.3358 - accuracy: 0.8824
Epoch 25: val_loss improved from 0.63402 to 0.61536, saving model to best-model.h5
708/708 [==============================] - 19s 28ms/step - loss: 0.3356 - accuracy: 0.8825 - val_loss: 0.6154 - val_accuracy: 0.8196 - lr: 1.0000e-04
Epoch 26/30
707/708 [============================>.] - ETA: 0s - loss: 0.3156 - accuracy: 0.8876
Epoch 26: val_loss did not improve from 0.61536
708/708 [==============================] - 19s 27ms/step - loss: 0.3155 - accuracy: 0.8876 - val_loss: 0.6564 - val_accuracy: 0.8149 - lr: 1.0000e-04
Epoch 27/30
707/708 [============================>.] - ETA: 0s - loss: 0.2953 - accuracy: 0.8956
Epoch 27: val_loss did not improve from 0.61536
708/708 [==============================] - 19s 27ms/step - loss: 0.2954 - accuracy: 0.8955 - val_loss: 0.6456 - val_accuracy: 0.8220 - lr: 1.0000e-04
Epoch 28/30
707/708 [============================>.] - ETA: 0s - loss: 0.2780 - accuracy: 0.9001
Epoch 28: val_loss did not improve from 0.61536

Epoch 28: ReduceLROnPlateau reducing learning rate to 3.1622775802825264e-05.
708/708 [==============================] - 19s 27ms/step - loss: 0.2778 - accuracy: 0.9002 - val_loss: 0.6661 - val_accuracy: 0.8184 - lr: 1.0000e-04
Epoch 29/30
707/708 [============================>.] - ETA: 0s - loss: 0.2288 - accuracy: 0.9198
Epoch 29: val_loss did not improve from 0.61536
708/708 [==============================] - 19s 27ms/step - loss: 0.2287 - accuracy: 0.9198 - val_loss: 0.6326 - val_accuracy: 0.8292 - lr: 3.1623e-05
Epoch 30/30
707/708 [============================>.] - ETA: 0s - loss: 0.2092 - accuracy: 0.9271
Epoch 30: val_loss did not improve from 0.61536
708/708 [==============================] - 19s 27ms/step - loss: 0.2092 - accuracy: 0.9271 - val_loss: 0.6329 - val_accuracy: 0.8333 - lr: 3.1623e-05
394/394 [==============================] - 3s 6ms/step - loss: 0.6354 - accuracy: 0.8319
Out[ ]:
[0.6354373097419739, 0.8318633437156677]

CNN Model 2 with Data Augmentation

In [ ]:
train_datagen = ImageDataGenerator(
    rotation_range=35,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.4,
    zoom_range=0.4,
    fill_mode='nearest'
)

plot_augmentation_samples(train_datagen)
Data Augmentation Samples has been saved
In [ ]:
model = model_2()

history4 = train_augmented_model(model, train_datagen, 80, 128)
model.evaluate(x_test, y_test)
Epoch 1/80
352/353 [============================>.] - ETA: 0s - loss: 2.4151 - accuracy: 0.1679
Epoch 1: val_loss improved from inf to 2.17855, saving model to best-model.h5
353/353 [==============================] - 18s 48ms/step - loss: 2.4149 - accuracy: 0.1679 - val_loss: 2.1786 - val_accuracy: 0.1263 - lr: 1.0000e-04
Epoch 2/80
352/353 [============================>.] - ETA: 0s - loss: 2.1947 - accuracy: 0.1784
Epoch 2: val_loss improved from 2.17855 to 2.04914, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 2.1945 - accuracy: 0.1785 - val_loss: 2.0491 - val_accuracy: 0.1780 - lr: 1.0000e-04
Epoch 3/80
352/353 [============================>.] - ETA: 0s - loss: 2.1224 - accuracy: 0.1852
Epoch 3: val_loss improved from 2.04914 to 1.90840, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 2.1224 - accuracy: 0.1853 - val_loss: 1.9084 - val_accuracy: 0.2304 - lr: 1.0000e-04
Epoch 4/80
352/353 [============================>.] - ETA: 0s - loss: 2.0820 - accuracy: 0.1900
Epoch 4: val_loss improved from 1.90840 to 1.85000, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 2.0817 - accuracy: 0.1900 - val_loss: 1.8500 - val_accuracy: 0.2584 - lr: 1.0000e-04
Epoch 5/80
353/353 [==============================] - ETA: 0s - loss: 2.0474 - accuracy: 0.1988
Epoch 5: val_loss improved from 1.85000 to 1.84210, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 2.0474 - accuracy: 0.1988 - val_loss: 1.8421 - val_accuracy: 0.2576 - lr: 1.0000e-04
Epoch 6/80
353/353 [==============================] - ETA: 0s - loss: 2.0189 - accuracy: 0.2052
Epoch 6: val_loss did not improve from 1.84210
353/353 [==============================] - 17s 48ms/step - loss: 2.0189 - accuracy: 0.2052 - val_loss: 1.8569 - val_accuracy: 0.2586 - lr: 1.0000e-04
Epoch 7/80
353/353 [==============================] - ETA: 0s - loss: 1.9859 - accuracy: 0.2183
Epoch 7: val_loss improved from 1.84210 to 1.79480, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.9859 - accuracy: 0.2183 - val_loss: 1.7948 - val_accuracy: 0.2863 - lr: 1.0000e-04
Epoch 8/80
353/353 [==============================] - ETA: 0s - loss: 1.9596 - accuracy: 0.2279
Epoch 8: val_loss improved from 1.79480 to 1.78370, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.9596 - accuracy: 0.2279 - val_loss: 1.7837 - val_accuracy: 0.2938 - lr: 1.0000e-04
Epoch 9/80
352/353 [============================>.] - ETA: 0s - loss: 1.9354 - accuracy: 0.2398
Epoch 9: val_loss improved from 1.78370 to 1.77796, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.9354 - accuracy: 0.2398 - val_loss: 1.7780 - val_accuracy: 0.3000 - lr: 1.0000e-04
Epoch 10/80
352/353 [============================>.] - ETA: 0s - loss: 1.9080 - accuracy: 0.2507
Epoch 10: val_loss improved from 1.77796 to 1.77499, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.9079 - accuracy: 0.2508 - val_loss: 1.7750 - val_accuracy: 0.3063 - lr: 1.0000e-04
Epoch 11/80
353/353 [==============================] - ETA: 0s - loss: 1.8712 - accuracy: 0.2653
Epoch 11: val_loss improved from 1.77499 to 1.71581, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.8712 - accuracy: 0.2653 - val_loss: 1.7158 - val_accuracy: 0.3216 - lr: 1.0000e-04
Epoch 12/80
352/353 [============================>.] - ETA: 0s - loss: 1.8310 - accuracy: 0.2789
Epoch 12: val_loss improved from 1.71581 to 1.70240, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.8312 - accuracy: 0.2791 - val_loss: 1.7024 - val_accuracy: 0.3453 - lr: 1.0000e-04
Epoch 13/80
353/353 [==============================] - ETA: 0s - loss: 1.8039 - accuracy: 0.2915
Epoch 13: val_loss improved from 1.70240 to 1.66093, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.8039 - accuracy: 0.2915 - val_loss: 1.6609 - val_accuracy: 0.3530 - lr: 1.0000e-04
Epoch 14/80
352/353 [============================>.] - ETA: 0s - loss: 1.7600 - accuracy: 0.3138
Epoch 14: val_loss improved from 1.66093 to 1.64650, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.7599 - accuracy: 0.3138 - val_loss: 1.6465 - val_accuracy: 0.3884 - lr: 1.0000e-04
Epoch 15/80
352/353 [============================>.] - ETA: 0s - loss: 1.7225 - accuracy: 0.3311
Epoch 15: val_loss did not improve from 1.64650
353/353 [==============================] - 17s 48ms/step - loss: 1.7221 - accuracy: 0.3313 - val_loss: 1.7554 - val_accuracy: 0.3758 - lr: 1.0000e-04
Epoch 16/80
353/353 [==============================] - ETA: 0s - loss: 1.6864 - accuracy: 0.3464
Epoch 16: val_loss improved from 1.64650 to 1.53418, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.6864 - accuracy: 0.3464 - val_loss: 1.5342 - val_accuracy: 0.4319 - lr: 1.0000e-04
Epoch 17/80
353/353 [==============================] - ETA: 0s - loss: 1.6479 - accuracy: 0.3628
Epoch 17: val_loss did not improve from 1.53418
353/353 [==============================] - 17s 48ms/step - loss: 1.6479 - accuracy: 0.3628 - val_loss: 1.5923 - val_accuracy: 0.4154 - lr: 1.0000e-04
Epoch 18/80
352/353 [============================>.] - ETA: 0s - loss: 1.6029 - accuracy: 0.3839
Epoch 18: val_loss improved from 1.53418 to 1.48758, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.6031 - accuracy: 0.3838 - val_loss: 1.4876 - val_accuracy: 0.4507 - lr: 1.0000e-04
Epoch 19/80
352/353 [============================>.] - ETA: 0s - loss: 1.5732 - accuracy: 0.3981
Epoch 19: val_loss improved from 1.48758 to 1.42675, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.5731 - accuracy: 0.3982 - val_loss: 1.4267 - val_accuracy: 0.4692 - lr: 1.0000e-04
Epoch 20/80
353/353 [==============================] - ETA: 0s - loss: 1.5424 - accuracy: 0.4076
Epoch 20: val_loss improved from 1.42675 to 1.42401, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.5424 - accuracy: 0.4076 - val_loss: 1.4240 - val_accuracy: 0.4760 - lr: 1.0000e-04
Epoch 21/80
352/353 [============================>.] - ETA: 0s - loss: 1.5160 - accuracy: 0.4187
Epoch 21: val_loss improved from 1.42401 to 1.30537, saving model to best-model.h5
353/353 [==============================] - 21s 61ms/step - loss: 1.5158 - accuracy: 0.4189 - val_loss: 1.3054 - val_accuracy: 0.5139 - lr: 1.0000e-04
Epoch 22/80
353/353 [==============================] - ETA: 0s - loss: 1.4908 - accuracy: 0.4288
Epoch 22: val_loss improved from 1.30537 to 1.28653, saving model to best-model.h5
353/353 [==============================] - 20s 56ms/step - loss: 1.4908 - accuracy: 0.4288 - val_loss: 1.2865 - val_accuracy: 0.5226 - lr: 1.0000e-04
Epoch 23/80
353/353 [==============================] - ETA: 0s - loss: 1.4651 - accuracy: 0.4389
Epoch 23: val_loss improved from 1.28653 to 1.27115, saving model to best-model.h5
353/353 [==============================] - 20s 56ms/step - loss: 1.4651 - accuracy: 0.4389 - val_loss: 1.2712 - val_accuracy: 0.5242 - lr: 1.0000e-04
Epoch 24/80
352/353 [============================>.] - ETA: 0s - loss: 1.4444 - accuracy: 0.4489
Epoch 24: val_loss improved from 1.27115 to 1.16613, saving model to best-model.h5
353/353 [==============================] - 19s 55ms/step - loss: 1.4446 - accuracy: 0.4489 - val_loss: 1.1661 - val_accuracy: 0.5626 - lr: 1.0000e-04
Epoch 25/80
352/353 [============================>.] - ETA: 0s - loss: 1.4178 - accuracy: 0.4587
Epoch 25: val_loss did not improve from 1.16613
353/353 [==============================] - 20s 57ms/step - loss: 1.4177 - accuracy: 0.4587 - val_loss: 1.2729 - val_accuracy: 0.5290 - lr: 1.0000e-04
Epoch 26/80
352/353 [============================>.] - ETA: 0s - loss: 1.4027 - accuracy: 0.4650
Epoch 26: val_loss improved from 1.16613 to 1.14209, saving model to best-model.h5
353/353 [==============================] - 20s 58ms/step - loss: 1.4028 - accuracy: 0.4649 - val_loss: 1.1421 - val_accuracy: 0.5747 - lr: 1.0000e-04
Epoch 27/80
353/353 [==============================] - ETA: 0s - loss: 1.3786 - accuracy: 0.4775
Epoch 27: val_loss did not improve from 1.14209
353/353 [==============================] - 20s 58ms/step - loss: 1.3786 - accuracy: 0.4775 - val_loss: 1.1561 - val_accuracy: 0.5675 - lr: 1.0000e-04
Epoch 28/80
353/353 [==============================] - ETA: 0s - loss: 1.3579 - accuracy: 0.4820
Epoch 28: val_loss did not improve from 1.14209
353/353 [==============================] - 17s 49ms/step - loss: 1.3579 - accuracy: 0.4820 - val_loss: 1.1442 - val_accuracy: 0.5739 - lr: 1.0000e-04
Epoch 29/80
353/353 [==============================] - ETA: 0s - loss: 1.3470 - accuracy: 0.4910Restoring model weights from the end of the best epoch: 26.

Epoch 29: val_loss improved from 1.14209 to 1.13374, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.3470 - accuracy: 0.4910 - val_loss: 1.1337 - val_accuracy: 0.5725 - lr: 1.0000e-04
Epoch 29: early stopping
394/394 [==============================] - 2s 6ms/step - loss: 1.1341 - accuracy: 0.5739
Out[ ]:
[1.134113073348999, 0.5738577842712402]

Initial Results

In [ ]:
plot_model_history(history1, name="CNN Model 1")
Min validation loss: 0.9167398810386658 
Max validation loss: 1.5393399000167847 
Min validation acc: 0.41815653443336487 
Max validation acc: 0.7904251217842102
In [ ]:
plot_model_history(history2, name="CNN Model 2")
Min validation loss: 0.5889896154403687 
Max validation loss: 2.0088906288146973 
Min validation acc: 0.24374255537986755 
Max validation acc: 0.8458482027053833
In [ ]:
plot_model_history(history3, name="CNN Model 2 with Leaky ReLu")
Min validation loss: 0.6021990776062012 
Max validation loss: 2.0196313858032227 
Min validation acc: 0.2445371448993683 
Max validation acc: 0.8373063206672668
In [ ]:
plot_model_history(history4, name="CNN Model 2 with Data Augmentation")
Min validation loss: 1.1337430477142334 
Max validation loss: 2.1785547733306885 
Min validation acc: 0.12634088099002838 
Max validation acc: 0.5746920704841614

After analysing all the results, Model 2 has proven to be the most promising. Therefore, it will be shortlisted for fine-tuning.

Hyperparameter Optimisation

Tuning the activation functions and pooling types

In [ ]:
def create_model(pool_type='max', conv_activation='relu', dropout_rate=0.25):
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation=conv_activation, input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  if pool_type == 'max':
    model.add(layers.MaxPooling2D((2, 2)))
  if pool_type == 'average':
    model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))    

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation=conv_activation))
  model.add(layers.BatchNormalization())
  if pool_type == 'max':
    model.add(layers.MaxPooling2D((2, 2)))
  if pool_type == 'average':
    model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 3rd convolutional layer
  model.add(layers.Conv2D(256, kernel_size=3, strides=1, padding='same', activation=conv_activation))
  model.add(layers.BatchNormalization())
  if pool_type == 'max':
    model.add(layers.MaxPooling2D((2, 2)))
  if pool_type == 'average':
    model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 4th convolutional layer
  model.add(layers.Conv2D(256, kernel_size=3, strides=1, padding='same', activation=conv_activation))
  model.add(layers.BatchNormalization())
  if pool_type == 'max':  
    model.add(layers.MaxPooling2D((2, 2)))
  if pool_type == 'average':
    model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation=conv_activation))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 2nd fully connected dense layer
  model.add(layers.Dense(256, activation=conv_activation))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [ ]:
# wrapping the existing model around KerasClassifier to use it with scikit-learn
model = KerasClassifier(build_fn=create_model, pool_type='max', conv_activation='relu', dropout_rate=0.25, verbose=1)

# specifying the hyperparameters to be tuned during the grid search 
param_grid = {
    'pool_type': ['max', 'average'],
    'conv_activation': ['relu', tf.keras.layers.LeakyReLU(), 'tanh'],    
    'epochs': [30],
}

# fitting the model and evaluating the results
grid_searcher = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_searcher_result = grid_searcher.fit(x_train, y_train)
plot_grid_search_results(grid_searcher_result)
/usr/local/lib/python3.7/dist-packages/joblib/externals/loky/process_executor.py:705: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.
  "timeout or by a memory leak.", UserWarning
/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py:290: UserWarning: ``build_fn`` will be renamed to ``model`` in a future release, at which point use of ``build_fn`` will raise an Error instead.
  "``build_fn`` will be renamed to ``model`` in a future release,"
Epoch 1/30
1416/1416 [==============================] - 18s 11ms/step - loss: 2.2184 - accuracy: 0.2192
Epoch 2/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.8781 - accuracy: 0.3062
Epoch 3/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.6445 - accuracy: 0.3893
Epoch 4/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.4567 - accuracy: 0.4571
Epoch 5/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.3201 - accuracy: 0.5069
Epoch 6/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.2144 - accuracy: 0.5461
Epoch 7/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.1278 - accuracy: 0.5776
Epoch 8/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.0592 - accuracy: 0.6029
Epoch 9/30
1416/1416 [==============================] - 15s 10ms/step - loss: 1.0053 - accuracy: 0.6250
Epoch 10/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.9522 - accuracy: 0.6444
Epoch 11/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.9075 - accuracy: 0.6607
Epoch 12/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.8627 - accuracy: 0.6782
Epoch 13/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.8262 - accuracy: 0.6938
Epoch 14/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.7885 - accuracy: 0.7070
Epoch 15/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.7523 - accuracy: 0.7236
Epoch 16/30
1416/1416 [==============================] - 15s 11ms/step - loss: 0.7189 - accuracy: 0.7374
Epoch 17/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.6873 - accuracy: 0.7483
Epoch 18/30
1416/1416 [==============================] - 15s 11ms/step - loss: 0.6593 - accuracy: 0.7576
Epoch 19/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.6233 - accuracy: 0.7750
Epoch 20/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.6011 - accuracy: 0.7815
Epoch 21/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.5733 - accuracy: 0.7929
Epoch 22/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.5470 - accuracy: 0.7998
Epoch 23/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.5272 - accuracy: 0.8117
Epoch 24/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.5046 - accuracy: 0.8180
Epoch 25/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.4824 - accuracy: 0.8254
Epoch 26/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.4662 - accuracy: 0.8337
Epoch 27/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.4502 - accuracy: 0.8398
Epoch 28/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.4390 - accuracy: 0.8434
Epoch 29/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.4211 - accuracy: 0.8478
Epoch 30/30
1416/1416 [==============================] - 15s 10ms/step - loss: 0.4092 - accuracy: 0.8535

Best score = 0.76 using {'conv_activation': 'relu', 'epochs': 30, 'pool_type': 'average'}

394/394 [==============================] - 2s 3ms/step
mean test accuracy +/- std = 0.7515 +/- 0.0096 with: {'conv_activation': 'relu', 'epochs': 30, 'pool_type': 'max'}
mean test accuracy +/- std = 0.7629 +/- 0.0031 with: {'conv_activation': 'relu', 'epochs': 30, 'pool_type': 'average'}
mean test accuracy +/- std = 0.7486 +/- 0.0021 with: {'conv_activation': <keras.layers.advanced_activations.LeakyReLU object at 0x7fdc431aad50>, 'epochs': 30, 'pool_type': 'max'}
mean test accuracy +/- std = 0.6814 +/- 0.0067 with: {'conv_activation': <keras.layers.advanced_activations.LeakyReLU object at 0x7fdc431aad50>, 'epochs': 30, 'pool_type': 'average'}
mean test accuracy +/- std = 0.6862 +/- 0.0048 with: {'conv_activation': 'tanh', 'epochs': 30, 'pool_type': 'max'}
mean test accuracy +/- std = 0.7000 +/- 0.0054 with: {'conv_activation': 'tanh', 'epochs': 30, 'pool_type': 'average'}

Accuracy achieved on the best model
81.89%

Tuning the kernel size and dropout regularisation

In [ ]:
def create_model(kernel_size=3, dropout_rate=0.25):
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=kernel_size, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))    

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 3rd convolutional layer
  model.add(layers.Conv2D(256, kernel_size=kernel_size, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 4th convolutional layer
  model.add(layers.Conv2D(256, kernel_size=kernel_size, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 2nd fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [ ]:
# wrapping the existing model around KerasClassifier to use it with scikit-learn
model = KerasClassifier(build_fn=create_model, kernel_size=3, dropout_rate=0.25, verbose=1)

# specifying the hyperparameters to be tuned during the grid search 
param_grid = {
    'kernel_size': [3, 5, 7],
    'dropout_rate': [0.2, 0.25, 0.3, 0.35],
    'epochs': [30],
    'batch_size': [64, 128],
}

# fitting the model and evaluating the results
grid_searcher = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_searcher_result = grid_searcher.fit(x_train, y_train)
plot_grid_search_results(grid_searcher_result)
/usr/local/lib/python3.7/dist-packages/joblib/externals/loky/process_executor.py:705: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.
  "timeout or by a memory leak.", UserWarning
/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py:290: UserWarning: ``build_fn`` will be renamed to ``model`` in a future release, at which point use of ``build_fn`` will raise an Error instead.
  "``build_fn`` will be renamed to ``model`` in a future release,"
Epoch 1/30
354/354 [==============================] - 11s 25ms/step - loss: 2.1357 - accuracy: 0.2430
Epoch 2/30
354/354 [==============================] - 8s 24ms/step - loss: 1.7797 - accuracy: 0.3546
Epoch 3/30
354/354 [==============================] - 8s 24ms/step - loss: 1.5331 - accuracy: 0.4419
Epoch 4/30
354/354 [==============================] - 8s 24ms/step - loss: 1.3613 - accuracy: 0.4999
Epoch 5/30
354/354 [==============================] - 8s 24ms/step - loss: 1.2353 - accuracy: 0.5421
Epoch 6/30
354/354 [==============================] - 8s 24ms/step - loss: 1.1381 - accuracy: 0.5813
Epoch 7/30
354/354 [==============================] - 8s 24ms/step - loss: 1.0502 - accuracy: 0.6088
Epoch 8/30
354/354 [==============================] - 8s 24ms/step - loss: 0.9773 - accuracy: 0.6392
Epoch 9/30
354/354 [==============================] - 8s 24ms/step - loss: 0.9136 - accuracy: 0.6638
Epoch 10/30
354/354 [==============================] - 8s 24ms/step - loss: 0.8483 - accuracy: 0.6879
Epoch 11/30
354/354 [==============================] - 8s 24ms/step - loss: 0.7951 - accuracy: 0.7080
Epoch 12/30
354/354 [==============================] - 8s 24ms/step - loss: 0.7383 - accuracy: 0.7301
Epoch 13/30
354/354 [==============================] - 8s 24ms/step - loss: 0.6926 - accuracy: 0.7489
Epoch 14/30
354/354 [==============================] - 8s 24ms/step - loss: 0.6388 - accuracy: 0.7697
Epoch 15/30
354/354 [==============================] - 8s 24ms/step - loss: 0.5879 - accuracy: 0.7885
Epoch 16/30
354/354 [==============================] - 8s 24ms/step - loss: 0.5482 - accuracy: 0.8049
Epoch 17/30
354/354 [==============================] - 8s 24ms/step - loss: 0.4958 - accuracy: 0.8241
Epoch 18/30
354/354 [==============================] - 8s 24ms/step - loss: 0.4542 - accuracy: 0.8385
Epoch 19/30
354/354 [==============================] - 8s 24ms/step - loss: 0.4140 - accuracy: 0.8532
Epoch 20/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3834 - accuracy: 0.8642
Epoch 21/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3483 - accuracy: 0.8770
Epoch 22/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3257 - accuracy: 0.8841
Epoch 23/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3013 - accuracy: 0.8942
Epoch 24/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2706 - accuracy: 0.9050
Epoch 25/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2500 - accuracy: 0.9106
Epoch 26/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2282 - accuracy: 0.9208
Epoch 27/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2141 - accuracy: 0.9255
Epoch 28/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2019 - accuracy: 0.9307
Epoch 29/30
354/354 [==============================] - 8s 24ms/step - loss: 0.1895 - accuracy: 0.9342
Epoch 30/30
354/354 [==============================] - 8s 24ms/step - loss: 0.1757 - accuracy: 0.9399
Best score = 0.77 using {'batch_size': 128, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 5}

99/99 [==============================] - 1s 8ms/step
mean test accuracy +/- std = 0.7654 +/- 0.0032 with: {'batch_size': 64, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7696 +/- 0.0012 with: {'batch_size': 64, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7603 +/- 0.0047 with: {'batch_size': 64, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.7426 +/- 0.0040 with: {'batch_size': 64, 'dropout_rate': 0.25, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7689 +/- 0.0036 with: {'batch_size': 64, 'dropout_rate': 0.25, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7636 +/- 0.0023 with: {'batch_size': 64, 'dropout_rate': 0.25, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.7127 +/- 0.0012 with: {'batch_size': 64, 'dropout_rate': 0.3, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7625 +/- 0.0018 with: {'batch_size': 64, 'dropout_rate': 0.3, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7677 +/- 0.0038 with: {'batch_size': 64, 'dropout_rate': 0.3, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.6865 +/- 0.0077 with: {'batch_size': 64, 'dropout_rate': 0.35, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7373 +/- 0.0093 with: {'batch_size': 64, 'dropout_rate': 0.35, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7626 +/- 0.0059 with: {'batch_size': 64, 'dropout_rate': 0.35, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.7378 +/- 0.0032 with: {'batch_size': 128, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7701 +/- 0.0056 with: {'batch_size': 128, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7597 +/- 0.0025 with: {'batch_size': 128, 'dropout_rate': 0.2, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.7061 +/- 0.0090 with: {'batch_size': 128, 'dropout_rate': 0.25, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7544 +/- 0.0058 with: {'batch_size': 128, 'dropout_rate': 0.25, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7617 +/- 0.0025 with: {'batch_size': 128, 'dropout_rate': 0.25, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.6794 +/- 0.0053 with: {'batch_size': 128, 'dropout_rate': 0.3, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.7261 +/- 0.0066 with: {'batch_size': 128, 'dropout_rate': 0.3, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7596 +/- 0.0012 with: {'batch_size': 128, 'dropout_rate': 0.3, 'epochs': 30, 'kernel_size': 7}
mean test accuracy +/- std = 0.6521 +/- 0.0059 with: {'batch_size': 128, 'dropout_rate': 0.35, 'epochs': 30, 'kernel_size': 3}
mean test accuracy +/- std = 0.6997 +/- 0.0024 with: {'batch_size': 128, 'dropout_rate': 0.35, 'epochs': 30, 'kernel_size': 5}
mean test accuracy +/- std = 0.7321 +/- 0.0095 with: {'batch_size': 128, 'dropout_rate': 0.35, 'epochs': 30, 'kernel_size': 7}

Accuracy achieved on the best model
83.35%

Tuning the padding

In [ ]:
def create_model(padding='same', dropout_rate=0.2):
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=5, strides=1, padding=padding, activation='relu', input_shape=(48, 48, 1)))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))    

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding=padding, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 3rd convolutional layer
  model.add(layers.Conv2D(256, kernel_size=5, strides=1, padding=padding, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 4th convolutional layer
  model.add(layers.Conv2D(256, kernel_size=5, strides=1, padding=padding, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 2nd fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [ ]:
# wrapping the existing model around KerasClassifier to use it with scikit-learn
model = KerasClassifier(build_fn=create_model, padding='same', dropout_rate=0.2, verbose=1)

# specifying the hyperparameters to be tuned during the grid search 
param_grid = {
    'padding': ['same', 'valid', 'causal'],
    'epochs': [30],
    'batch_size': [128],
}

# fitting the model and evaluating the results
grid_searcher = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_searcher_result = grid_searcher.fit(x_train, y_train)
plot_grid_search_results(grid_searcher_result)
/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_validation.py:372: FitFailedWarning: 
6 fits failed out of a total of 9.
The score on these train-test partitions for these parameters will be set to nan.
If these failures are not expected, you can try to debug them by setting error_score='raise'.

Below are more details about the failures:
--------------------------------------------------------------------------------
1 fits failed with the following error:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_validation.py", line 680, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 1453, in fit
    super().fit(X=X, y=y, sample_weight=sample_weight, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 726, in fit
    X=X, y=y, sample_weight=sample_weight, warm_start=self.warm_start, **kwargs,
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 877, in _fit
    X, y = self._initialize(X, y)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 814, in _initialize
    self.model_ = self._build_keras_model()
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 408, in _build_keras_model
    model = final_build_fn(**build_params)
  File "<ipython-input-112-d6a8404a65bf>", line 26, in create_model
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/training/tracking/base.py", line 629, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py", line 305, in compute_output_shape
    f'One of the dimensions in the output is <= 0 '
ValueError: One of the dimensions in the output is <= 0 due to downsampling in conv2d_3. Consider increasing the input size. Received input shape [None, 2, 2, 256] which would produce output shape with a zero or negative value in a dimension.

--------------------------------------------------------------------------------
1 fits failed with the following error:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_validation.py", line 680, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 1453, in fit
    super().fit(X=X, y=y, sample_weight=sample_weight, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 726, in fit
    X=X, y=y, sample_weight=sample_weight, warm_start=self.warm_start, **kwargs,
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 877, in _fit
    X, y = self._initialize(X, y)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 814, in _initialize
    self.model_ = self._build_keras_model()
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 408, in _build_keras_model
    model = final_build_fn(**build_params)
  File "<ipython-input-112-d6a8404a65bf>", line 26, in create_model
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/training/tracking/base.py", line 629, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py", line 305, in compute_output_shape
    f'One of the dimensions in the output is <= 0 '
ValueError: One of the dimensions in the output is <= 0 due to downsampling in conv2d_7. Consider increasing the input size. Received input shape [None, 2, 2, 256] which would produce output shape with a zero or negative value in a dimension.

--------------------------------------------------------------------------------
1 fits failed with the following error:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_validation.py", line 680, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 1453, in fit
    super().fit(X=X, y=y, sample_weight=sample_weight, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 726, in fit
    X=X, y=y, sample_weight=sample_weight, warm_start=self.warm_start, **kwargs,
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 877, in _fit
    X, y = self._initialize(X, y)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 814, in _initialize
    self.model_ = self._build_keras_model()
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 408, in _build_keras_model
    model = final_build_fn(**build_params)
  File "<ipython-input-112-d6a8404a65bf>", line 26, in create_model
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/training/tracking/base.py", line 629, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py", line 305, in compute_output_shape
    f'One of the dimensions in the output is <= 0 '
ValueError: One of the dimensions in the output is <= 0 due to downsampling in conv2d_11. Consider increasing the input size. Received input shape [None, 2, 2, 256] which would produce output shape with a zero or negative value in a dimension.

--------------------------------------------------------------------------------
3 fits failed with the following error:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_validation.py", line 680, in _fit_and_score
    estimator.fit(X_train, y_train, **fit_params)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 1453, in fit
    super().fit(X=X, y=y, sample_weight=sample_weight, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 726, in fit
    X=X, y=y, sample_weight=sample_weight, warm_start=self.warm_start, **kwargs,
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 877, in _fit
    X, y = self._initialize(X, y)
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 814, in _initialize
    self.model_ = self._build_keras_model()
  File "/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py", line 408, in _build_keras_model
    model = final_build_fn(**build_params)
  File "<ipython-input-112-d6a8404a65bf>", line 5, in create_model
  File "/usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py", line 691, in __init__
    **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py", line 159, in __init__
    self._validate_init()
  File "/usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py", line 182, in _validate_init
    raise ValueError('Causal padding is only supported for `Conv1D`'
ValueError: Causal padding is only supported for `Conv1D`and `SeparableConv1D`.

  warnings.warn(some_fits_failed_message, FitFailedWarning)
/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_search.py:972: UserWarning: One or more of the test scores are non-finite: [0.76602515        nan        nan]
  category=UserWarning,
/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py:290: UserWarning: ``build_fn`` will be renamed to ``model`` in a future release, at which point use of ``build_fn`` will raise an Error instead.
  "``build_fn`` will be renamed to ``model`` in a future release,"
Epoch 1/30
354/354 [==============================] - 10s 24ms/step - loss: 2.1119 - accuracy: 0.2486
Epoch 2/30
354/354 [==============================] - 8s 24ms/step - loss: 1.7603 - accuracy: 0.3606
Epoch 3/30
354/354 [==============================] - 8s 24ms/step - loss: 1.5295 - accuracy: 0.4397
Epoch 4/30
354/354 [==============================] - 8s 24ms/step - loss: 1.3559 - accuracy: 0.4989
Epoch 5/30
354/354 [==============================] - 9s 24ms/step - loss: 1.2279 - accuracy: 0.5445
Epoch 6/30
354/354 [==============================] - 8s 24ms/step - loss: 1.1251 - accuracy: 0.5804
Epoch 7/30
354/354 [==============================] - 8s 24ms/step - loss: 1.0421 - accuracy: 0.6133
Epoch 8/30
354/354 [==============================] - 8s 24ms/step - loss: 0.9696 - accuracy: 0.6388
Epoch 9/30
354/354 [==============================] - 9s 24ms/step - loss: 0.9070 - accuracy: 0.6643
Epoch 10/30
354/354 [==============================] - 8s 24ms/step - loss: 0.8489 - accuracy: 0.6857
Epoch 11/30
354/354 [==============================] - 8s 24ms/step - loss: 0.7909 - accuracy: 0.7079
Epoch 12/30
354/354 [==============================] - 8s 24ms/step - loss: 0.7389 - accuracy: 0.7277
Epoch 13/30
354/354 [==============================] - 8s 24ms/step - loss: 0.6904 - accuracy: 0.7483
Epoch 14/30
354/354 [==============================] - 8s 24ms/step - loss: 0.6402 - accuracy: 0.7678
Epoch 15/30
354/354 [==============================] - 8s 24ms/step - loss: 0.5968 - accuracy: 0.7864
Epoch 16/30
354/354 [==============================] - 9s 24ms/step - loss: 0.5423 - accuracy: 0.8058
Epoch 17/30
354/354 [==============================] - 8s 24ms/step - loss: 0.5035 - accuracy: 0.8220
Epoch 18/30
354/354 [==============================] - 8s 24ms/step - loss: 0.4606 - accuracy: 0.8363
Epoch 19/30
354/354 [==============================] - 8s 24ms/step - loss: 0.4221 - accuracy: 0.8524
Epoch 20/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3885 - accuracy: 0.8637
Epoch 21/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3564 - accuracy: 0.8742
Epoch 22/30
354/354 [==============================] - 9s 24ms/step - loss: 0.3275 - accuracy: 0.8839
Epoch 23/30
354/354 [==============================] - 8s 24ms/step - loss: 0.3058 - accuracy: 0.8920
Epoch 24/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2838 - accuracy: 0.8989
Epoch 25/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2604 - accuracy: 0.9089
Epoch 26/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2419 - accuracy: 0.9153
Epoch 27/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2236 - accuracy: 0.9214
Epoch 28/30
354/354 [==============================] - 8s 24ms/step - loss: 0.2090 - accuracy: 0.9263
Epoch 29/30
354/354 [==============================] - 9s 24ms/step - loss: 0.1947 - accuracy: 0.9330
Epoch 30/30
354/354 [==============================] - 8s 24ms/step - loss: 0.1791 - accuracy: 0.9372

Best score = 0.77 using {'batch_size': 128, 'epochs': 30, 'padding': 'same'}

99/99 [==============================] - 1s 7ms/step
mean test accuracy +/- std = 0.7660 +/- 0.0025 with: {'batch_size': 128, 'epochs': 30, 'padding': 'same'}
mean test accuracy +/- std = nan +/- nan with: {'batch_size': 128, 'epochs': 30, 'padding': 'valid'}
mean test accuracy +/- std = nan +/- nan with: {'batch_size': 128, 'epochs': 30, 'padding': 'causal'}

Accuracy achieved on the best model
83.95%

Tuning the optimiser and learning rate

In [ ]:
def create_model(optimizer=optimizers.Adam, learning_rate=0.0001, dropout_rate=0.2):
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))    

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 3rd convolutional layer
  model.add(layers.Conv2D(256, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 4th convolutional layer
  model.add(layers.Conv2D(256, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # 2nd fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  if dropout_rate != 0:
    model.add(layers.Dropout(dropout_rate))  

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizer(learning_rate), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [ ]:
# wrapping the existing model around KerasClassifier to use it with scikit-learn
model = KerasClassifier(build_fn=create_model, optimizer=optimizers.Adam, learning_rate=0.0001, dropout_rate=0.2, verbose=1)

# specifying the hyperparameters to be tuned during the grid search 
param_grid = {
    'optimizer': [optimizers.RMSprop, optimizers.Adagrad, optimizers.Adam, optimizers.Adamax, optimizers.Nadam],
    'learning_rate': [0.0001, 0.00001, 0.0005, 0.00005],
    'epochs': [30],
    'batch_size': [64, 128],
}

# fitting the model and evaluating the results
grid_searcher = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_searcher_result = grid_searcher.fit(x_train, y_train)
plot_grid_search_results(grid_searcher_result)
/usr/local/lib/python3.7/dist-packages/joblib/externals/loky/process_executor.py:705: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.
  "timeout or by a memory leak.", UserWarning
/usr/local/lib/python3.7/dist-packages/scikeras/wrappers.py:290: UserWarning: ``build_fn`` will be renamed to ``model`` in a future release, at which point use of ``build_fn`` will raise an Error instead.
  "``build_fn`` will be renamed to ``model`` in a future release,"
Epoch 1/30
708/708 [==============================] - 16s 18ms/step - loss: 2.0423 - accuracy: 0.2424
Epoch 2/30
708/708 [==============================] - 12s 18ms/step - loss: 1.5573 - accuracy: 0.4130
Epoch 3/30
708/708 [==============================] - 12s 18ms/step - loss: 1.2539 - accuracy: 0.5278
Epoch 4/30
708/708 [==============================] - 12s 18ms/step - loss: 1.0888 - accuracy: 0.5898
Epoch 5/30
708/708 [==============================] - 13s 18ms/step - loss: 0.9752 - accuracy: 0.6335
Epoch 6/30
708/708 [==============================] - 12s 18ms/step - loss: 0.9010 - accuracy: 0.6619
Epoch 7/30
708/708 [==============================] - 12s 18ms/step - loss: 0.8291 - accuracy: 0.6890
Epoch 8/30
708/708 [==============================] - 12s 18ms/step - loss: 0.7633 - accuracy: 0.7181
Epoch 9/30
708/708 [==============================] - 12s 18ms/step - loss: 0.7059 - accuracy: 0.7399
Epoch 10/30
708/708 [==============================] - 12s 18ms/step - loss: 0.6468 - accuracy: 0.7653
Epoch 11/30
708/708 [==============================] - 12s 18ms/step - loss: 0.6094 - accuracy: 0.7775
Epoch 12/30
708/708 [==============================] - 12s 18ms/step - loss: 0.5601 - accuracy: 0.7981
Epoch 13/30
708/708 [==============================] - 12s 18ms/step - loss: 0.5241 - accuracy: 0.8126
Epoch 14/30
708/708 [==============================] - 12s 18ms/step - loss: 0.4873 - accuracy: 0.8249
Epoch 15/30
708/708 [==============================] - 12s 18ms/step - loss: 0.4613 - accuracy: 0.8348
Epoch 16/30
708/708 [==============================] - 12s 18ms/step - loss: 0.4387 - accuracy: 0.8428
Epoch 17/30
708/708 [==============================] - 12s 18ms/step - loss: 0.4085 - accuracy: 0.8540
Epoch 18/30
708/708 [==============================] - 12s 18ms/step - loss: 0.3905 - accuracy: 0.8606
Epoch 19/30
708/708 [==============================] - 12s 18ms/step - loss: 0.3707 - accuracy: 0.8684
Epoch 20/30
708/708 [==============================] - 12s 18ms/step - loss: 0.3581 - accuracy: 0.8721
Epoch 21/30
708/708 [==============================] - 12s 18ms/step - loss: 0.3389 - accuracy: 0.8792
Epoch 22/30
708/708 [==============================] - 12s 18ms/step - loss: 0.3244 - accuracy: 0.8856
Epoch 23/30
708/708 [==============================] - 12s 18ms/step - loss: 0.3148 - accuracy: 0.8875
Epoch 24/30
708/708 [==============================] - 12s 18ms/step - loss: 0.2960 - accuracy: 0.8951
Epoch 25/30
708/708 [==============================] - 12s 18ms/step - loss: 0.2884 - accuracy: 0.8982
Epoch 26/30
708/708 [==============================] - 12s 18ms/step - loss: 0.2817 - accuracy: 0.9020
Epoch 27/30
708/708 [==============================] - 12s 18ms/step - loss: 0.2704 - accuracy: 0.9036
Epoch 28/30
708/708 [==============================] - 12s 18ms/step - loss: 0.2582 - accuracy: 0.9084
Epoch 29/30
708/708 [==============================] - 12s 18ms/step - loss: 0.2531 - accuracy: 0.9097
Epoch 30/30
708/708 [==============================] - 13s 18ms/step - loss: 0.2484 - accuracy: 0.9133

Best score = 0.79 using {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}

197/197 [==============================] - 2s 6ms/step
mean test accuracy +/- std = 0.7445 +/- 0.0037 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.7432 +/- 0.0043 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.7471 +/- 0.0035 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.7421 +/- 0.0042 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.7468 +/- 0.0011 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.4606 +/- 0.0042 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.4621 +/- 0.0115 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.4690 +/- 0.0029 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.4538 +/- 0.0054 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.4599 +/- 0.0187 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.7816 +/- 0.0043 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.7754 +/- 0.0072 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.7815 +/- 0.0036 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.7872 +/- 0.0066 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.7795 +/- 0.0035 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.6685 +/- 0.0036 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.6718 +/- 0.0032 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.6753 +/- 0.0063 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.6742 +/- 0.0034 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.6725 +/- 0.0072 with: {'batch_size': 64, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.7088 +/- 0.0038 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.7078 +/- 0.0029 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.7112 +/- 0.0039 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.7156 +/- 0.0050 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.7094 +/- 0.0056 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0001, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.4130 +/- 0.0021 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.4246 +/- 0.0048 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.4200 +/- 0.0088 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.4194 +/- 0.0033 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.4116 +/- 0.0059 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 1e-05, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.7807 +/- 0.0059 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.7802 +/- 0.0050 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.7817 +/- 0.0054 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.7687 +/- 0.0105 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.7798 +/- 0.0033 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 0.0005, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}
mean test accuracy +/- std = 0.6317 +/- 0.0044 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.rmsprop.RMSprop'>}
mean test accuracy +/- std = 0.6318 +/- 0.0037 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.adagrad.Adagrad'>}
mean test accuracy +/- std = 0.6313 +/- 0.0013 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.adam.Adam'>}
mean test accuracy +/- std = 0.6347 +/- 0.0064 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.adamax.Adamax'>}
mean test accuracy +/- std = 0.6310 +/- 0.0105 with: {'batch_size': 128, 'epochs': 30, 'learning_rate': 5e-05, 'optimizer': <class 'keras.optimizer_v2.nadam.Nadam'>}

Accuracy achieved on the best model
83.31%

Combining Models

ReLu Activation with Average Pooling

In [34]:
def combined_model_1():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.25))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [35]:
model = combined_model_1()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[35]:
In [36]:
model.summary()
Model: "sequential_3"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_13 (Conv2D)          (None, 48, 48, 64)        640       
                                                                 
 batch_normalization_12 (Bat  (None, 48, 48, 64)       256       
 chNormalization)                                                
                                                                 
 average_pooling2d (AverageP  (None, 24, 24, 64)       0         
 ooling2D)                                                       
                                                                 
 dropout_12 (Dropout)        (None, 24, 24, 64)        0         
                                                                 
 conv2d_14 (Conv2D)          (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_13 (Bat  (None, 24, 24, 128)      512       
 chNormalization)                                                
                                                                 
 average_pooling2d_1 (Averag  (None, 12, 12, 128)      0         
 ePooling2D)                                                     
                                                                 
 dropout_13 (Dropout)        (None, 12, 12, 128)       0         
                                                                 
 conv2d_15 (Conv2D)          (None, 12, 12, 512)       590336    
                                                                 
 batch_normalization_14 (Bat  (None, 12, 12, 512)      2048      
 chNormalization)                                                
                                                                 
 average_pooling2d_2 (Averag  (None, 6, 6, 512)        0         
 ePooling2D)                                                     
                                                                 
 dropout_14 (Dropout)        (None, 6, 6, 512)         0         
                                                                 
 conv2d_16 (Conv2D)          (None, 6, 6, 512)         2359808   
                                                                 
 batch_normalization_15 (Bat  (None, 6, 6, 512)        2048      
 chNormalization)                                                
                                                                 
 average_pooling2d_3 (Averag  (None, 3, 3, 512)        0         
 ePooling2D)                                                     
                                                                 
 dropout_15 (Dropout)        (None, 3, 3, 512)         0         
                                                                 
 flatten_3 (Flatten)         (None, 4608)              0         
                                                                 
 dense_8 (Dense)             (None, 256)               1179904   
                                                                 
 batch_normalization_16 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_16 (Dropout)        (None, 256)               0         
                                                                 
 dense_9 (Dense)             (None, 512)               131584    
                                                                 
 batch_normalization_17 (Bat  (None, 512)              2048      
 chNormalization)                                                
                                                                 
 dropout_17 (Dropout)        (None, 512)               0         
                                                                 
 dense_10 (Dense)            (None, 7)                 3591      
                                                                 
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history5 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
707/708 [============================>.] - ETA: 0s - loss: 2.1996 - accuracy: 0.2309
Epoch 1: val_loss improved from inf to 1.81243, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 2.1993 - accuracy: 0.2310 - val_loss: 1.8124 - val_accuracy: 0.3270 - lr: 1.0000e-04
Epoch 2/30
708/708 [==============================] - ETA: 0s - loss: 1.8299 - accuracy: 0.3392
Epoch 2: val_loss improved from 1.81243 to 1.61387, saving model to best-model.h5
708/708 [==============================] - 18s 25ms/step - loss: 1.8299 - accuracy: 0.3392 - val_loss: 1.6139 - val_accuracy: 0.4120 - lr: 1.0000e-04
Epoch 3/30
708/708 [==============================] - ETA: 0s - loss: 1.5866 - accuracy: 0.4211
Epoch 3: val_loss improved from 1.61387 to 1.30976, saving model to best-model.h5
708/708 [==============================] - 18s 25ms/step - loss: 1.5866 - accuracy: 0.4211 - val_loss: 1.3098 - val_accuracy: 0.5028 - lr: 1.0000e-04
Epoch 4/30
707/708 [============================>.] - ETA: 0s - loss: 1.4040 - accuracy: 0.4848
Epoch 4: val_loss improved from 1.30976 to 1.17384, saving model to best-model.h5
708/708 [==============================] - 18s 25ms/step - loss: 1.4040 - accuracy: 0.4849 - val_loss: 1.1738 - val_accuracy: 0.5602 - lr: 1.0000e-04
Epoch 5/30
708/708 [==============================] - ETA: 0s - loss: 1.2695 - accuracy: 0.5281
Epoch 5: val_loss improved from 1.17384 to 1.07224, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.2695 - accuracy: 0.5281 - val_loss: 1.0722 - val_accuracy: 0.5961 - lr: 1.0000e-04
Epoch 6/30
708/708 [==============================] - ETA: 0s - loss: 1.1556 - accuracy: 0.5696
Epoch 6: val_loss improved from 1.07224 to 1.06693, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.1556 - accuracy: 0.5696 - val_loss: 1.0669 - val_accuracy: 0.6033 - lr: 1.0000e-04
Epoch 7/30
706/708 [============================>.] - ETA: 0s - loss: 1.0677 - accuracy: 0.6018
Epoch 7: val_loss improved from 1.06693 to 0.92752, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.0677 - accuracy: 0.6017 - val_loss: 0.9275 - val_accuracy: 0.6563 - lr: 1.0000e-04
Epoch 8/30
707/708 [============================>.] - ETA: 0s - loss: 0.9901 - accuracy: 0.6311
Epoch 8: val_loss improved from 0.92752 to 0.89566, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.9901 - accuracy: 0.6311 - val_loss: 0.8957 - val_accuracy: 0.6677 - lr: 1.0000e-04
Epoch 9/30
706/708 [============================>.] - ETA: 0s - loss: 0.9288 - accuracy: 0.6550
Epoch 9: val_loss improved from 0.89566 to 0.89384, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.9290 - accuracy: 0.6550 - val_loss: 0.8938 - val_accuracy: 0.6619 - lr: 1.0000e-04
Epoch 10/30
706/708 [============================>.] - ETA: 0s - loss: 0.8630 - accuracy: 0.6804
Epoch 10: val_loss improved from 0.89384 to 0.81526, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.8633 - accuracy: 0.6803 - val_loss: 0.8153 - val_accuracy: 0.6990 - lr: 1.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.8123 - accuracy: 0.7023
Epoch 11: val_loss improved from 0.81526 to 0.80827, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.8121 - accuracy: 0.7022 - val_loss: 0.8083 - val_accuracy: 0.6971 - lr: 1.0000e-04
Epoch 12/30
706/708 [============================>.] - ETA: 0s - loss: 0.7586 - accuracy: 0.7189
Epoch 12: val_loss improved from 0.80827 to 0.76015, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.7582 - accuracy: 0.7190 - val_loss: 0.7601 - val_accuracy: 0.7187 - lr: 1.0000e-04
Epoch 13/30
707/708 [============================>.] - ETA: 0s - loss: 0.7097 - accuracy: 0.7393
Epoch 13: val_loss improved from 0.76015 to 0.71031, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.7096 - accuracy: 0.7393 - val_loss: 0.7103 - val_accuracy: 0.7429 - lr: 1.0000e-04
Epoch 14/30
706/708 [============================>.] - ETA: 0s - loss: 0.6573 - accuracy: 0.7593
Epoch 14: val_loss improved from 0.71031 to 0.70321, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.6574 - accuracy: 0.7593 - val_loss: 0.7032 - val_accuracy: 0.7535 - lr: 1.0000e-04
Epoch 15/30
708/708 [==============================] - ETA: 0s - loss: 0.6038 - accuracy: 0.7809
Epoch 15: val_loss improved from 0.70321 to 0.66662, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.6038 - accuracy: 0.7809 - val_loss: 0.6666 - val_accuracy: 0.7676 - lr: 1.0000e-04
Epoch 16/30
706/708 [============================>.] - ETA: 0s - loss: 0.5641 - accuracy: 0.7966
Epoch 16: val_loss improved from 0.66662 to 0.64667, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.5646 - accuracy: 0.7964 - val_loss: 0.6467 - val_accuracy: 0.7767 - lr: 1.0000e-04
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.5217 - accuracy: 0.8131
Epoch 17: val_loss improved from 0.64667 to 0.62553, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.5215 - accuracy: 0.8132 - val_loss: 0.6255 - val_accuracy: 0.7841 - lr: 1.0000e-04
Epoch 18/30
707/708 [============================>.] - ETA: 0s - loss: 0.4774 - accuracy: 0.8277
Epoch 18: val_loss improved from 0.62553 to 0.61250, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.4773 - accuracy: 0.8277 - val_loss: 0.6125 - val_accuracy: 0.7960 - lr: 1.0000e-04
Epoch 19/30
707/708 [============================>.] - ETA: 0s - loss: 0.4496 - accuracy: 0.8390
Epoch 19: val_loss improved from 0.61250 to 0.60485, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.4499 - accuracy: 0.8388 - val_loss: 0.6049 - val_accuracy: 0.8049 - lr: 1.0000e-04
Epoch 20/30
706/708 [============================>.] - ETA: 0s - loss: 0.4145 - accuracy: 0.8523
Epoch 20: val_loss improved from 0.60485 to 0.59340, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.4142 - accuracy: 0.8524 - val_loss: 0.5934 - val_accuracy: 0.8157 - lr: 1.0000e-04
Epoch 21/30
708/708 [==============================] - ETA: 0s - loss: 0.3832 - accuracy: 0.8639
Epoch 21: val_loss did not improve from 0.59340
708/708 [==============================] - 18s 26ms/step - loss: 0.3832 - accuracy: 0.8639 - val_loss: 0.6258 - val_accuracy: 0.8103 - lr: 1.0000e-04
Epoch 22/30
706/708 [============================>.] - ETA: 0s - loss: 0.3568 - accuracy: 0.8748
Epoch 22: val_loss improved from 0.59340 to 0.58912, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.3569 - accuracy: 0.8747 - val_loss: 0.5891 - val_accuracy: 0.8246 - lr: 1.0000e-04
Epoch 23/30
707/708 [============================>.] - ETA: 0s - loss: 0.3309 - accuracy: 0.8821
Epoch 23: val_loss did not improve from 0.58912
708/708 [==============================] - 18s 26ms/step - loss: 0.3310 - accuracy: 0.8821 - val_loss: 0.5921 - val_accuracy: 0.8268 - lr: 1.0000e-04
Epoch 24/30
708/708 [==============================] - ETA: 0s - loss: 0.3063 - accuracy: 0.8930
Epoch 24: val_loss did not improve from 0.58912
708/708 [==============================] - 18s 26ms/step - loss: 0.3063 - accuracy: 0.8930 - val_loss: 0.5935 - val_accuracy: 0.8302 - lr: 1.0000e-04
Epoch 25/30
707/708 [============================>.] - ETA: 0s - loss: 0.2837 - accuracy: 0.8995
Epoch 25: val_loss did not improve from 0.58912

Epoch 25: ReduceLROnPlateau reducing learning rate to 3.1622775802825264e-05.
708/708 [==============================] - 18s 26ms/step - loss: 0.2836 - accuracy: 0.8995 - val_loss: 0.6047 - val_accuracy: 0.8232 - lr: 1.0000e-04
Epoch 26/30
706/708 [============================>.] - ETA: 0s - loss: 0.2312 - accuracy: 0.9183
Epoch 26: val_loss improved from 0.58912 to 0.55925, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.2311 - accuracy: 0.9184 - val_loss: 0.5592 - val_accuracy: 0.8399 - lr: 3.1623e-05
Epoch 27/30
708/708 [==============================] - ETA: 0s - loss: 0.2059 - accuracy: 0.9280
Epoch 27: val_loss did not improve from 0.55925
708/708 [==============================] - 18s 26ms/step - loss: 0.2059 - accuracy: 0.9280 - val_loss: 0.5644 - val_accuracy: 0.8403 - lr: 3.1623e-05
Epoch 28/30
707/708 [============================>.] - ETA: 0s - loss: 0.1920 - accuracy: 0.9313
Epoch 28: val_loss did not improve from 0.55925
708/708 [==============================] - 18s 26ms/step - loss: 0.1919 - accuracy: 0.9313 - val_loss: 0.5725 - val_accuracy: 0.8445 - lr: 3.1623e-05
Epoch 29/30
706/708 [============================>.] - ETA: 0s - loss: 0.1794 - accuracy: 0.9375
Epoch 29: val_loss did not improve from 0.55925

Epoch 29: ReduceLROnPlateau reducing learning rate to 9.999999259090306e-06.
708/708 [==============================] - 18s 26ms/step - loss: 0.1794 - accuracy: 0.9375 - val_loss: 0.5857 - val_accuracy: 0.8413 - lr: 3.1623e-05
Epoch 30/30
707/708 [============================>.] - ETA: 0s - loss: 0.1643 - accuracy: 0.9437
Epoch 30: val_loss did not improve from 0.55925
708/708 [==============================] - 18s 26ms/step - loss: 0.1645 - accuracy: 0.9437 - val_loss: 0.5789 - val_accuracy: 0.8449 - lr: 1.0000e-05
394/394 [==============================] - 2s 6ms/step - loss: 0.6089 - accuracy: 0.8439
Out[ ]:
[0.6088735461235046, 0.8438617587089539]
Combine Model 1 Results
In [ ]:
plot_model_history(history5, name="Combined Model 1")
Min validation loss: 0.5592455863952637 
Max validation loss: 1.812427282333374 
Min validation acc: 0.32697656750679016 
Max validation acc: 0.844855010509491
Model 2 vs Combine Model 1
In [ ]:
compare_model_history(history2, history5, name="Model 2 vs Combined Model 1", key1="Model 2", key2="Combined Model 1")
Model 2 validation loss: 0.5889896154403687 
Combined Model 1 validation loss: 0.5592455863952637

Model 2 validation accuracy: 0.8458482027053833 
Combined Model 1 validation accuracy: 0.844855010509491

Kernel Size of 5 with Dropout Regularisation of 0.2

In [37]:
def combined_model_2():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=5, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.2))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.2))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.2))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.2))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.2))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.2))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adam(0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [38]:
model = combined_model_2()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[38]:
In [39]:
model.summary()
Model: "sequential_4"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_17 (Conv2D)          (None, 48, 48, 64)        1664      
                                                                 
 batch_normalization_18 (Bat  (None, 48, 48, 64)       256       
 chNormalization)                                                
                                                                 
 max_pooling2d_11 (MaxPoolin  (None, 24, 24, 64)       0         
 g2D)                                                            
                                                                 
 dropout_18 (Dropout)        (None, 24, 24, 64)        0         
                                                                 
 conv2d_18 (Conv2D)          (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_19 (Bat  (None, 24, 24, 128)      512       
 chNormalization)                                                
                                                                 
 max_pooling2d_12 (MaxPoolin  (None, 12, 12, 128)      0         
 g2D)                                                            
                                                                 
 dropout_19 (Dropout)        (None, 12, 12, 128)       0         
                                                                 
 conv2d_19 (Conv2D)          (None, 12, 12, 512)       1638912   
                                                                 
 batch_normalization_20 (Bat  (None, 12, 12, 512)      2048      
 chNormalization)                                                
                                                                 
 max_pooling2d_13 (MaxPoolin  (None, 6, 6, 512)        0         
 g2D)                                                            
                                                                 
 dropout_20 (Dropout)        (None, 6, 6, 512)         0         
                                                                 
 conv2d_20 (Conv2D)          (None, 6, 6, 512)         6554112   
                                                                 
 batch_normalization_21 (Bat  (None, 6, 6, 512)        2048      
 chNormalization)                                                
                                                                 
 max_pooling2d_14 (MaxPoolin  (None, 3, 3, 512)        0         
 g2D)                                                            
                                                                 
 dropout_21 (Dropout)        (None, 3, 3, 512)         0         
                                                                 
 flatten_4 (Flatten)         (None, 4608)              0         
                                                                 
 dense_11 (Dense)            (None, 256)               1179904   
                                                                 
 batch_normalization_22 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_22 (Dropout)        (None, 256)               0         
                                                                 
 dense_12 (Dense)            (None, 512)               131584    
                                                                 
 batch_normalization_23 (Bat  (None, 512)              2048      
 chNormalization)                                                
                                                                 
 dropout_23 (Dropout)        (None, 512)               0         
                                                                 
 dense_13 (Dense)            (None, 7)                 3591      
                                                                 
=================================================================
Total params: 9,722,631
Trainable params: 9,718,663
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history6 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
707/708 [============================>.] - ETA: 0s - loss: 2.0732 - accuracy: 0.2627
Epoch 1: val_loss improved from inf to 2.02089, saving model to best-model.h5
708/708 [==============================] - 32s 43ms/step - loss: 2.0727 - accuracy: 0.2628 - val_loss: 2.0209 - val_accuracy: 0.2960 - lr: 1.0000e-04
Epoch 2/30
707/708 [============================>.] - ETA: 0s - loss: 1.6464 - accuracy: 0.4002
Epoch 2: val_loss improved from 2.02089 to 1.44083, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 1.6462 - accuracy: 0.4004 - val_loss: 1.4408 - val_accuracy: 0.4688 - lr: 1.0000e-04
Epoch 3/30
707/708 [============================>.] - ETA: 0s - loss: 1.3828 - accuracy: 0.4893
Epoch 3: val_loss improved from 1.44083 to 1.23598, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 1.3827 - accuracy: 0.4894 - val_loss: 1.2360 - val_accuracy: 0.5348 - lr: 1.0000e-04
Epoch 4/30
707/708 [============================>.] - ETA: 0s - loss: 1.1872 - accuracy: 0.5614
Epoch 4: val_loss improved from 1.23598 to 1.04890, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 1.1873 - accuracy: 0.5613 - val_loss: 1.0489 - val_accuracy: 0.6075 - lr: 1.0000e-04
Epoch 5/30
707/708 [============================>.] - ETA: 0s - loss: 1.0364 - accuracy: 0.6131
Epoch 5: val_loss improved from 1.04890 to 0.93198, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 1.0364 - accuracy: 0.6130 - val_loss: 0.9320 - val_accuracy: 0.6589 - lr: 1.0000e-04
Epoch 6/30
707/708 [============================>.] - ETA: 0s - loss: 0.8909 - accuracy: 0.6699
Epoch 6: val_loss improved from 0.93198 to 0.85500, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 0.8907 - accuracy: 0.6700 - val_loss: 0.8550 - val_accuracy: 0.6838 - lr: 1.0000e-04
Epoch 7/30
707/708 [============================>.] - ETA: 0s - loss: 0.7717 - accuracy: 0.7169
Epoch 7: val_loss improved from 0.85500 to 0.82079, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 0.7715 - accuracy: 0.7170 - val_loss: 0.8208 - val_accuracy: 0.7066 - lr: 1.0000e-04
Epoch 8/30
707/708 [============================>.] - ETA: 0s - loss: 0.6481 - accuracy: 0.7652
Epoch 8: val_loss improved from 0.82079 to 0.71901, saving model to best-model.h5
708/708 [==============================] - 30s 42ms/step - loss: 0.6482 - accuracy: 0.7652 - val_loss: 0.7190 - val_accuracy: 0.7513 - lr: 1.0000e-04
Epoch 9/30
707/708 [============================>.] - ETA: 0s - loss: 0.5285 - accuracy: 0.8127
Epoch 9: val_loss improved from 0.71901 to 0.67376, saving model to best-model.h5
708/708 [==============================] - 30s 43ms/step - loss: 0.5284 - accuracy: 0.8127 - val_loss: 0.6738 - val_accuracy: 0.7813 - lr: 1.0000e-04
Epoch 10/30
707/708 [============================>.] - ETA: 0s - loss: 0.4246 - accuracy: 0.8510
Epoch 10: val_loss improved from 0.67376 to 0.62551, saving model to best-model.h5
708/708 [==============================] - 30s 43ms/step - loss: 0.4246 - accuracy: 0.8511 - val_loss: 0.6255 - val_accuracy: 0.8043 - lr: 1.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.3390 - accuracy: 0.8817
Epoch 11: val_loss did not improve from 0.62551
708/708 [==============================] - 30s 42ms/step - loss: 0.3390 - accuracy: 0.8818 - val_loss: 0.6462 - val_accuracy: 0.8053 - lr: 1.0000e-04
Epoch 12/30
707/708 [============================>.] - ETA: 0s - loss: 0.2717 - accuracy: 0.9057
Epoch 12: val_loss did not improve from 0.62551
708/708 [==============================] - 30s 42ms/step - loss: 0.2719 - accuracy: 0.9056 - val_loss: 0.6768 - val_accuracy: 0.8111 - lr: 1.0000e-04
Epoch 13/30
707/708 [============================>.] - ETA: 0s - loss: 0.2352 - accuracy: 0.9179
Epoch 13: val_loss did not improve from 0.62551

Epoch 13: ReduceLROnPlateau reducing learning rate to 3.1622775802825264e-05.
708/708 [==============================] - 30s 42ms/step - loss: 0.2355 - accuracy: 0.9178 - val_loss: 0.6850 - val_accuracy: 0.8149 - lr: 1.0000e-04
Epoch 14/30
707/708 [============================>.] - ETA: 0s - loss: 0.1432 - accuracy: 0.9522
Epoch 14: val_loss improved from 0.62551 to 0.62316, saving model to best-model.h5
708/708 [==============================] - 30s 43ms/step - loss: 0.1432 - accuracy: 0.9522 - val_loss: 0.6232 - val_accuracy: 0.8351 - lr: 3.1623e-05
Epoch 15/30
707/708 [============================>.] - ETA: 0s - loss: 0.1054 - accuracy: 0.9650
Epoch 15: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.1054 - accuracy: 0.9649 - val_loss: 0.6567 - val_accuracy: 0.8319 - lr: 3.1623e-05
Epoch 16/30
707/708 [============================>.] - ETA: 0s - loss: 0.0859 - accuracy: 0.9729
Epoch 16: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0860 - accuracy: 0.9729 - val_loss: 0.6682 - val_accuracy: 0.8367 - lr: 3.1623e-05
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.0736 - accuracy: 0.9763
Epoch 17: val_loss did not improve from 0.62316

Epoch 17: ReduceLROnPlateau reducing learning rate to 9.999999259090306e-06.
708/708 [==============================] - 30s 42ms/step - loss: 0.0736 - accuracy: 0.9763 - val_loss: 0.6944 - val_accuracy: 0.8331 - lr: 3.1623e-05
Epoch 18/30
707/708 [============================>.] - ETA: 0s - loss: 0.0600 - accuracy: 0.9812
Epoch 18: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0599 - accuracy: 0.9812 - val_loss: 0.6876 - val_accuracy: 0.8327 - lr: 1.0000e-05
Epoch 19/30
707/708 [============================>.] - ETA: 0s - loss: 0.0558 - accuracy: 0.9827
Epoch 19: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0557 - accuracy: 0.9827 - val_loss: 0.6867 - val_accuracy: 0.8327 - lr: 1.0000e-05
Epoch 20/30
707/708 [============================>.] - ETA: 0s - loss: 0.0498 - accuracy: 0.9844
Epoch 20: val_loss did not improve from 0.62316

Epoch 20: ReduceLROnPlateau reducing learning rate to 3.162277292675049e-06.
708/708 [==============================] - 30s 42ms/step - loss: 0.0497 - accuracy: 0.9844 - val_loss: 0.6903 - val_accuracy: 0.8381 - lr: 1.0000e-05
Epoch 21/30
707/708 [============================>.] - ETA: 0s - loss: 0.0475 - accuracy: 0.9851
Epoch 21: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0474 - accuracy: 0.9851 - val_loss: 0.6940 - val_accuracy: 0.8375 - lr: 3.1623e-06
Epoch 22/30
707/708 [============================>.] - ETA: 0s - loss: 0.0439 - accuracy: 0.9863
Epoch 22: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0439 - accuracy: 0.9863 - val_loss: 0.6932 - val_accuracy: 0.8383 - lr: 3.1623e-06
Epoch 23/30
707/708 [============================>.] - ETA: 0s - loss: 0.0422 - accuracy: 0.9863
Epoch 23: val_loss did not improve from 0.62316

Epoch 23: ReduceLROnPlateau reducing learning rate to 9.999999115286567e-07.
708/708 [==============================] - 30s 42ms/step - loss: 0.0422 - accuracy: 0.9863 - val_loss: 0.6935 - val_accuracy: 0.8395 - lr: 3.1623e-06
Epoch 24/30
707/708 [============================>.] - ETA: 0s - loss: 0.0442 - accuracy: 0.9855
Epoch 24: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0442 - accuracy: 0.9855 - val_loss: 0.6983 - val_accuracy: 0.8387 - lr: 1.0000e-06
Epoch 25/30
707/708 [============================>.] - ETA: 0s - loss: 0.0418 - accuracy: 0.9872
Epoch 25: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0418 - accuracy: 0.9872 - val_loss: 0.6994 - val_accuracy: 0.8381 - lr: 1.0000e-06
Epoch 26/30
707/708 [============================>.] - ETA: 0s - loss: 0.0416 - accuracy: 0.9869
Epoch 26: val_loss did not improve from 0.62316

Epoch 26: ReduceLROnPlateau reducing learning rate to 3.1622772926750485e-07.
708/708 [==============================] - 30s 42ms/step - loss: 0.0416 - accuracy: 0.9869 - val_loss: 0.6983 - val_accuracy: 0.8383 - lr: 1.0000e-06
Epoch 27/30
707/708 [============================>.] - ETA: 0s - loss: 0.0427 - accuracy: 0.9866
Epoch 27: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0427 - accuracy: 0.9866 - val_loss: 0.6984 - val_accuracy: 0.8395 - lr: 3.1623e-07
Epoch 28/30
707/708 [============================>.] - ETA: 0s - loss: 0.0408 - accuracy: 0.9874
Epoch 28: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0408 - accuracy: 0.9874 - val_loss: 0.6990 - val_accuracy: 0.8397 - lr: 3.1623e-07
Epoch 29/30
707/708 [============================>.] - ETA: 0s - loss: 0.0393 - accuracy: 0.9878
Epoch 29: val_loss did not improve from 0.62316

Epoch 29: ReduceLROnPlateau reducing learning rate to 9.99999875577722e-08.
708/708 [==============================] - 30s 42ms/step - loss: 0.0393 - accuracy: 0.9878 - val_loss: 0.6973 - val_accuracy: 0.8395 - lr: 3.1623e-07
Epoch 30/30
707/708 [============================>.] - ETA: 0s - loss: 0.0400 - accuracy: 0.9877
Epoch 30: val_loss did not improve from 0.62316
708/708 [==============================] - 30s 42ms/step - loss: 0.0400 - accuracy: 0.9877 - val_loss: 0.6978 - val_accuracy: 0.8391 - lr: 1.0000e-07
394/394 [==============================] - 4s 10ms/step - loss: 0.7331 - accuracy: 0.8400
Out[ ]:
[0.733145534992218, 0.839968204498291]
Combined Model 2 Results
In [ ]:
plot_model_history(history6, name="Combined Model 2")
Min validation loss: 0.6231619715690613 
Max validation loss: 2.020892858505249 
Min validation acc: 0.2959872782230377 
Max validation acc: 0.839690089225769
Model 2 vs Combined Model 2
In [ ]:
compare_model_history(history2, history6, name="Model 2 vs Combined Model 2", key1="Model 2", key2="Combined Model 2")
Model 2 validation loss: 0.5889896154403687 
Combined Model 2 validation loss: 0.6231619715690613

Model 2 validation accuracy: 0.8458482027053833 
Combined Model 2 validation accuracy: 0.839690089225769

Adamax Optimiser with Learning Rate of 0.0005

In [40]:
def combined_model_3():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Dropout(0.25))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.25))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adamax(0.0005), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [41]:
model = combined_model_3()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[41]:
In [42]:
model.summary()
Model: "sequential_5"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_21 (Conv2D)          (None, 48, 48, 64)        640       
                                                                 
 batch_normalization_24 (Bat  (None, 48, 48, 64)       256       
 chNormalization)                                                
                                                                 
 max_pooling2d_15 (MaxPoolin  (None, 24, 24, 64)       0         
 g2D)                                                            
                                                                 
 dropout_24 (Dropout)        (None, 24, 24, 64)        0         
                                                                 
 conv2d_22 (Conv2D)          (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_25 (Bat  (None, 24, 24, 128)      512       
 chNormalization)                                                
                                                                 
 max_pooling2d_16 (MaxPoolin  (None, 12, 12, 128)      0         
 g2D)                                                            
                                                                 
 dropout_25 (Dropout)        (None, 12, 12, 128)       0         
                                                                 
 conv2d_23 (Conv2D)          (None, 12, 12, 512)       590336    
                                                                 
 batch_normalization_26 (Bat  (None, 12, 12, 512)      2048      
 chNormalization)                                                
                                                                 
 max_pooling2d_17 (MaxPoolin  (None, 6, 6, 512)        0         
 g2D)                                                            
                                                                 
 dropout_26 (Dropout)        (None, 6, 6, 512)         0         
                                                                 
 conv2d_24 (Conv2D)          (None, 6, 6, 512)         2359808   
                                                                 
 batch_normalization_27 (Bat  (None, 6, 6, 512)        2048      
 chNormalization)                                                
                                                                 
 max_pooling2d_18 (MaxPoolin  (None, 3, 3, 512)        0         
 g2D)                                                            
                                                                 
 dropout_27 (Dropout)        (None, 3, 3, 512)         0         
                                                                 
 flatten_5 (Flatten)         (None, 4608)              0         
                                                                 
 dense_14 (Dense)            (None, 256)               1179904   
                                                                 
 batch_normalization_28 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_28 (Dropout)        (None, 256)               0         
                                                                 
 dense_15 (Dense)            (None, 512)               131584    
                                                                 
 batch_normalization_29 (Bat  (None, 512)              2048      
 chNormalization)                                                
                                                                 
 dropout_29 (Dropout)        (None, 512)               0         
                                                                 
 dense_16 (Dense)            (None, 7)                 3591      
                                                                 
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history7 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
707/708 [============================>.] - ETA: 0s - loss: 2.1592 - accuracy: 0.2287
Epoch 1: val_loss improved from inf to 2.03815, saving model to best-model.h5
708/708 [==============================] - 20s 27ms/step - loss: 2.1588 - accuracy: 0.2288 - val_loss: 2.0381 - val_accuracy: 0.2515 - lr: 5.0000e-04
Epoch 2/30
706/708 [============================>.] - ETA: 0s - loss: 1.7901 - accuracy: 0.3404
Epoch 2: val_loss improved from 2.03815 to 1.59138, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.7895 - accuracy: 0.3405 - val_loss: 1.5914 - val_accuracy: 0.4146 - lr: 5.0000e-04
Epoch 3/30
707/708 [============================>.] - ETA: 0s - loss: 1.5113 - accuracy: 0.4379
Epoch 3: val_loss improved from 1.59138 to 1.41898, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.5110 - accuracy: 0.4380 - val_loss: 1.4190 - val_accuracy: 0.4787 - lr: 5.0000e-04
Epoch 4/30
707/708 [============================>.] - ETA: 0s - loss: 1.3195 - accuracy: 0.5036
Epoch 4: val_loss improved from 1.41898 to 1.12246, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.3194 - accuracy: 0.5036 - val_loss: 1.1225 - val_accuracy: 0.5725 - lr: 5.0000e-04
Epoch 5/30
706/708 [============================>.] - ETA: 0s - loss: 1.1660 - accuracy: 0.5620
Epoch 5: val_loss improved from 1.12246 to 1.02669, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.1657 - accuracy: 0.5621 - val_loss: 1.0267 - val_accuracy: 0.6063 - lr: 5.0000e-04
Epoch 6/30
708/708 [==============================] - ETA: 0s - loss: 1.0565 - accuracy: 0.6026
Epoch 6: val_loss improved from 1.02669 to 0.94135, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.0565 - accuracy: 0.6026 - val_loss: 0.9414 - val_accuracy: 0.6458 - lr: 5.0000e-04
Epoch 7/30
706/708 [============================>.] - ETA: 0s - loss: 0.9649 - accuracy: 0.6388
Epoch 7: val_loss improved from 0.94135 to 0.88472, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.9649 - accuracy: 0.6388 - val_loss: 0.8847 - val_accuracy: 0.6700 - lr: 5.0000e-04
Epoch 8/30
707/708 [============================>.] - ETA: 0s - loss: 0.8809 - accuracy: 0.6709
Epoch 8: val_loss improved from 0.88472 to 0.85902, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.8810 - accuracy: 0.6708 - val_loss: 0.8590 - val_accuracy: 0.6782 - lr: 5.0000e-04
Epoch 9/30
707/708 [============================>.] - ETA: 0s - loss: 0.8060 - accuracy: 0.7020
Epoch 9: val_loss improved from 0.85902 to 0.83001, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.8057 - accuracy: 0.7021 - val_loss: 0.8300 - val_accuracy: 0.6981 - lr: 5.0000e-04
Epoch 10/30
706/708 [============================>.] - ETA: 0s - loss: 0.7378 - accuracy: 0.7281
Epoch 10: val_loss improved from 0.83001 to 0.74577, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.7380 - accuracy: 0.7280 - val_loss: 0.7458 - val_accuracy: 0.7263 - lr: 5.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.6707 - accuracy: 0.7559
Epoch 11: val_loss did not improve from 0.74577
708/708 [==============================] - 19s 27ms/step - loss: 0.6711 - accuracy: 0.7557 - val_loss: 0.8433 - val_accuracy: 0.6881 - lr: 5.0000e-04
Epoch 12/30
708/708 [==============================] - ETA: 0s - loss: 0.5997 - accuracy: 0.7840
Epoch 12: val_loss improved from 0.74577 to 0.65467, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5997 - accuracy: 0.7840 - val_loss: 0.6547 - val_accuracy: 0.7676 - lr: 5.0000e-04
Epoch 13/30
707/708 [============================>.] - ETA: 0s - loss: 0.5458 - accuracy: 0.8034
Epoch 13: val_loss improved from 0.65467 to 0.62948, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5458 - accuracy: 0.8033 - val_loss: 0.6295 - val_accuracy: 0.7892 - lr: 5.0000e-04
Epoch 14/30
707/708 [============================>.] - ETA: 0s - loss: 0.4919 - accuracy: 0.8235
Epoch 14: val_loss improved from 0.62948 to 0.60042, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.4919 - accuracy: 0.8235 - val_loss: 0.6004 - val_accuracy: 0.8004 - lr: 5.0000e-04
Epoch 15/30
707/708 [============================>.] - ETA: 0s - loss: 0.4494 - accuracy: 0.8392
Epoch 15: val_loss did not improve from 0.60042
708/708 [==============================] - 19s 27ms/step - loss: 0.4495 - accuracy: 0.8392 - val_loss: 0.6400 - val_accuracy: 0.7886 - lr: 5.0000e-04
Epoch 16/30
707/708 [============================>.] - ETA: 0s - loss: 0.4043 - accuracy: 0.8567
Epoch 16: val_loss improved from 0.60042 to 0.59203, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.4045 - accuracy: 0.8567 - val_loss: 0.5920 - val_accuracy: 0.8147 - lr: 5.0000e-04
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.3703 - accuracy: 0.8673
Epoch 17: val_loss improved from 0.59203 to 0.58432, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.3702 - accuracy: 0.8673 - val_loss: 0.5843 - val_accuracy: 0.8206 - lr: 5.0000e-04
Epoch 18/30
708/708 [==============================] - ETA: 0s - loss: 0.3351 - accuracy: 0.8824
Epoch 18: val_loss did not improve from 0.58432
708/708 [==============================] - 19s 27ms/step - loss: 0.3351 - accuracy: 0.8824 - val_loss: 0.6047 - val_accuracy: 0.8230 - lr: 5.0000e-04
Epoch 19/30
707/708 [============================>.] - ETA: 0s - loss: 0.3089 - accuracy: 0.8913
Epoch 19: val_loss did not improve from 0.58432
708/708 [==============================] - 19s 27ms/step - loss: 0.3089 - accuracy: 0.8914 - val_loss: 0.6208 - val_accuracy: 0.8218 - lr: 5.0000e-04
Epoch 20/30
707/708 [============================>.] - ETA: 0s - loss: 0.2829 - accuracy: 0.9015
Epoch 20: val_loss did not improve from 0.58432

Epoch 20: ReduceLROnPlateau reducing learning rate to 0.00015811389051842542.
708/708 [==============================] - 19s 27ms/step - loss: 0.2829 - accuracy: 0.9015 - val_loss: 0.6188 - val_accuracy: 0.8250 - lr: 5.0000e-04
Epoch 21/30
706/708 [============================>.] - ETA: 0s - loss: 0.2224 - accuracy: 0.9219
Epoch 21: val_loss improved from 0.58432 to 0.58225, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.2222 - accuracy: 0.9220 - val_loss: 0.5823 - val_accuracy: 0.8393 - lr: 1.5811e-04
Epoch 22/30
707/708 [============================>.] - ETA: 0s - loss: 0.1973 - accuracy: 0.9305
Epoch 22: val_loss did not improve from 0.58225
708/708 [==============================] - 19s 27ms/step - loss: 0.1973 - accuracy: 0.9304 - val_loss: 0.5971 - val_accuracy: 0.8413 - lr: 1.5811e-04
Epoch 23/30
707/708 [============================>.] - ETA: 0s - loss: 0.1748 - accuracy: 0.9385
Epoch 23: val_loss did not improve from 0.58225
708/708 [==============================] - 19s 27ms/step - loss: 0.1747 - accuracy: 0.9386 - val_loss: 0.6127 - val_accuracy: 0.8405 - lr: 1.5811e-04
Epoch 24/30
707/708 [============================>.] - ETA: 0s - loss: 0.1646 - accuracy: 0.9440
Epoch 24: val_loss did not improve from 0.58225

Epoch 24: ReduceLROnPlateau reducing learning rate to 5.0000003198030994e-05.
708/708 [==============================] - 19s 27ms/step - loss: 0.1645 - accuracy: 0.9440 - val_loss: 0.6276 - val_accuracy: 0.8433 - lr: 1.5811e-04
Epoch 25/30
707/708 [============================>.] - ETA: 0s - loss: 0.1537 - accuracy: 0.9456
Epoch 25: val_loss did not improve from 0.58225
708/708 [==============================] - 19s 27ms/step - loss: 0.1537 - accuracy: 0.9456 - val_loss: 0.6209 - val_accuracy: 0.8437 - lr: 5.0000e-05
Epoch 26/30
706/708 [============================>.] - ETA: 0s - loss: 0.1469 - accuracy: 0.9497
Epoch 26: val_loss did not improve from 0.58225
708/708 [==============================] - 19s 27ms/step - loss: 0.1472 - accuracy: 0.9495 - val_loss: 0.6207 - val_accuracy: 0.8439 - lr: 5.0000e-05
Epoch 27/30
707/708 [============================>.] - ETA: 0s - loss: 0.1393 - accuracy: 0.9522
Epoch 27: val_loss did not improve from 0.58225

Epoch 27: ReduceLROnPlateau reducing learning rate to 1.5811389051842542e-05.
708/708 [==============================] - 19s 27ms/step - loss: 0.1393 - accuracy: 0.9522 - val_loss: 0.6223 - val_accuracy: 0.8421 - lr: 5.0000e-05
Epoch 28/30
708/708 [==============================] - ETA: 0s - loss: 0.1353 - accuracy: 0.9539
Epoch 28: val_loss did not improve from 0.58225
708/708 [==============================] - 19s 27ms/step - loss: 0.1353 - accuracy: 0.9539 - val_loss: 0.6233 - val_accuracy: 0.8431 - lr: 1.5811e-05
Epoch 29/30
707/708 [============================>.] - ETA: 0s - loss: 0.1344 - accuracy: 0.9540
Epoch 29: val_loss did not improve from 0.58225
708/708 [==============================] - 19s 27ms/step - loss: 0.1344 - accuracy: 0.9540 - val_loss: 0.6238 - val_accuracy: 0.8433 - lr: 1.5811e-05
Epoch 30/30
707/708 [============================>.] - ETA: 0s - loss: 0.1320 - accuracy: 0.9541
Epoch 30: val_loss did not improve from 0.58225

Epoch 30: ReduceLROnPlateau reducing learning rate to 5.000000204760109e-06.
708/708 [==============================] - 19s 27ms/step - loss: 0.1319 - accuracy: 0.9541 - val_loss: 0.6269 - val_accuracy: 0.8439 - lr: 1.5811e-05
394/394 [==============================] - 2s 6ms/step - loss: 0.6537 - accuracy: 0.8445
Out[ ]:
[0.6536846160888672, 0.8444974422454834]
Combined Model 3 Results
In [ ]:
plot_model_history(history7, name="Combined Model 3")
Min validation loss: 0.5822529792785645 
Max validation loss: 2.038146734237671 
Min validation acc: 0.25148987770080566 
Max validation acc: 0.8438617587089539
Model 2 vs Combined Model 3
In [ ]:
compare_model_history(history2, history7, name="Model 2 vs Combined Model 3", key1="Model 2", key2="Combined Model 3")
Model 2 validation loss: 0.5889896154403687 
Combined Model 3 validation loss: 0.5822529792785645

Model 2 validation accuracy: 0.8458482027053833 
Combined Model 3 validation accuracy: 0.8438617587089539

Final Combined Model

In [43]:
def final_combined_model():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.3))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.3))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adamax(0.0005), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [44]:
model = final_combined_model()
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Out[44]:
In [45]:
model.summary()
Model: "sequential_6"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_25 (Conv2D)          (None, 48, 48, 64)        640       
                                                                 
 batch_normalization_30 (Bat  (None, 48, 48, 64)       256       
 chNormalization)                                                
                                                                 
 average_pooling2d_4 (Averag  (None, 24, 24, 64)       0         
 ePooling2D)                                                     
                                                                 
 dropout_30 (Dropout)        (None, 24, 24, 64)        0         
                                                                 
 conv2d_26 (Conv2D)          (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_31 (Bat  (None, 24, 24, 128)      512       
 chNormalization)                                                
                                                                 
 average_pooling2d_5 (Averag  (None, 12, 12, 128)      0         
 ePooling2D)                                                     
                                                                 
 dropout_31 (Dropout)        (None, 12, 12, 128)       0         
                                                                 
 conv2d_27 (Conv2D)          (None, 12, 12, 512)       590336    
                                                                 
 batch_normalization_32 (Bat  (None, 12, 12, 512)      2048      
 chNormalization)                                                
                                                                 
 average_pooling2d_6 (Averag  (None, 6, 6, 512)        0         
 ePooling2D)                                                     
                                                                 
 dropout_32 (Dropout)        (None, 6, 6, 512)         0         
                                                                 
 conv2d_28 (Conv2D)          (None, 6, 6, 512)         2359808   
                                                                 
 batch_normalization_33 (Bat  (None, 6, 6, 512)        2048      
 chNormalization)                                                
                                                                 
 average_pooling2d_7 (Averag  (None, 3, 3, 512)        0         
 ePooling2D)                                                     
                                                                 
 dropout_33 (Dropout)        (None, 3, 3, 512)         0         
                                                                 
 flatten_6 (Flatten)         (None, 4608)              0         
                                                                 
 dense_17 (Dense)            (None, 256)               1179904   
                                                                 
 batch_normalization_34 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_34 (Dropout)        (None, 256)               0         
                                                                 
 dense_18 (Dense)            (None, 512)               131584    
                                                                 
 batch_normalization_35 (Bat  (None, 512)              2048      
 chNormalization)                                                
                                                                 
 dropout_35 (Dropout)        (None, 512)               0         
                                                                 
 dense_19 (Dense)            (None, 7)                 3591      
                                                                 
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history8 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
707/708 [============================>.] - ETA: 0s - loss: 2.2181 - accuracy: 0.2147
Epoch 1: val_loss improved from inf to 1.75674, saving model to best-model.h5
708/708 [==============================] - 20s 26ms/step - loss: 2.2177 - accuracy: 0.2149 - val_loss: 1.7567 - val_accuracy: 0.3117 - lr: 5.0000e-04
Epoch 2/30
707/708 [============================>.] - ETA: 0s - loss: 1.8615 - accuracy: 0.3190
Epoch 2: val_loss improved from 1.75674 to 1.53602, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.8609 - accuracy: 0.3193 - val_loss: 1.5360 - val_accuracy: 0.4213 - lr: 5.0000e-04
Epoch 3/30
708/708 [==============================] - ETA: 0s - loss: 1.5475 - accuracy: 0.4253
Epoch 3: val_loss improved from 1.53602 to 1.30146, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.5475 - accuracy: 0.4253 - val_loss: 1.3015 - val_accuracy: 0.5095 - lr: 5.0000e-04
Epoch 4/30
707/708 [============================>.] - ETA: 0s - loss: 1.3409 - accuracy: 0.4992
Epoch 4: val_loss improved from 1.30146 to 1.14279, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.3407 - accuracy: 0.4993 - val_loss: 1.1428 - val_accuracy: 0.5656 - lr: 5.0000e-04
Epoch 5/30
707/708 [============================>.] - ETA: 0s - loss: 1.1905 - accuracy: 0.5512
Epoch 5: val_loss improved from 1.14279 to 1.00718, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.1906 - accuracy: 0.5512 - val_loss: 1.0072 - val_accuracy: 0.6206 - lr: 5.0000e-04
Epoch 6/30
707/708 [============================>.] - ETA: 0s - loss: 1.0822 - accuracy: 0.5924
Epoch 6: val_loss improved from 1.00718 to 0.97151, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.0822 - accuracy: 0.5924 - val_loss: 0.9715 - val_accuracy: 0.6313 - lr: 5.0000e-04
Epoch 7/30
706/708 [============================>.] - ETA: 0s - loss: 0.9955 - accuracy: 0.6273
Epoch 7: val_loss improved from 0.97151 to 0.87965, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.9955 - accuracy: 0.6273 - val_loss: 0.8796 - val_accuracy: 0.6571 - lr: 5.0000e-04
Epoch 8/30
708/708 [==============================] - ETA: 0s - loss: 0.9230 - accuracy: 0.6549
Epoch 8: val_loss did not improve from 0.87965
708/708 [==============================] - 18s 26ms/step - loss: 0.9230 - accuracy: 0.6549 - val_loss: 0.8833 - val_accuracy: 0.6667 - lr: 5.0000e-04
Epoch 9/30
707/708 [============================>.] - ETA: 0s - loss: 0.8538 - accuracy: 0.6818
Epoch 9: val_loss improved from 0.87965 to 0.82398, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.8540 - accuracy: 0.6816 - val_loss: 0.8240 - val_accuracy: 0.6895 - lr: 5.0000e-04
Epoch 10/30
706/708 [============================>.] - ETA: 0s - loss: 0.7934 - accuracy: 0.7051
Epoch 10: val_loss improved from 0.82398 to 0.77713, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.7932 - accuracy: 0.7052 - val_loss: 0.7771 - val_accuracy: 0.7090 - lr: 5.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.7348 - accuracy: 0.7317
Epoch 11: val_loss did not improve from 0.77713
708/708 [==============================] - 18s 26ms/step - loss: 0.7347 - accuracy: 0.7317 - val_loss: 0.7794 - val_accuracy: 0.7114 - lr: 5.0000e-04
Epoch 12/30
706/708 [============================>.] - ETA: 0s - loss: 0.6830 - accuracy: 0.7482
Epoch 12: val_loss improved from 0.77713 to 0.69279, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.6826 - accuracy: 0.7483 - val_loss: 0.6928 - val_accuracy: 0.7471 - lr: 5.0000e-04
Epoch 13/30
708/708 [==============================] - ETA: 0s - loss: 0.6386 - accuracy: 0.7666
Epoch 13: val_loss did not improve from 0.69279
708/708 [==============================] - 18s 26ms/step - loss: 0.6386 - accuracy: 0.7666 - val_loss: 0.6931 - val_accuracy: 0.7485 - lr: 5.0000e-04
Epoch 14/30
706/708 [============================>.] - ETA: 0s - loss: 0.5910 - accuracy: 0.7849
Epoch 14: val_loss improved from 0.69279 to 0.63149, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.5912 - accuracy: 0.7849 - val_loss: 0.6315 - val_accuracy: 0.7795 - lr: 5.0000e-04
Epoch 15/30
706/708 [============================>.] - ETA: 0s - loss: 0.5432 - accuracy: 0.8024
Epoch 15: val_loss did not improve from 0.63149
708/708 [==============================] - 18s 26ms/step - loss: 0.5435 - accuracy: 0.8024 - val_loss: 0.6373 - val_accuracy: 0.7797 - lr: 5.0000e-04
Epoch 16/30
706/708 [============================>.] - ETA: 0s - loss: 0.5119 - accuracy: 0.8177
Epoch 16: val_loss improved from 0.63149 to 0.61047, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.5119 - accuracy: 0.8177 - val_loss: 0.6105 - val_accuracy: 0.7936 - lr: 5.0000e-04
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.4713 - accuracy: 0.8303
Epoch 17: val_loss improved from 0.61047 to 0.60110, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.4713 - accuracy: 0.8303 - val_loss: 0.6011 - val_accuracy: 0.8073 - lr: 5.0000e-04
Epoch 18/30
707/708 [============================>.] - ETA: 0s - loss: 0.4359 - accuracy: 0.8442
Epoch 18: val_loss did not improve from 0.60110
708/708 [==============================] - 18s 26ms/step - loss: 0.4363 - accuracy: 0.8441 - val_loss: 0.6074 - val_accuracy: 0.8021 - lr: 5.0000e-04
Epoch 19/30
708/708 [==============================] - ETA: 0s - loss: 0.4173 - accuracy: 0.8523
Epoch 19: val_loss did not improve from 0.60110
708/708 [==============================] - 18s 26ms/step - loss: 0.4173 - accuracy: 0.8523 - val_loss: 0.6035 - val_accuracy: 0.8089 - lr: 5.0000e-04
Epoch 20/30
706/708 [============================>.] - ETA: 0s - loss: 0.3870 - accuracy: 0.8610
Epoch 20: val_loss improved from 0.60110 to 0.58920, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 0.3869 - accuracy: 0.8611 - val_loss: 0.5892 - val_accuracy: 0.8202 - lr: 5.0000e-04
Epoch 21/30
708/708 [==============================] - ETA: 0s - loss: 0.3539 - accuracy: 0.8745
Epoch 21: val_loss improved from 0.58920 to 0.57808, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.3539 - accuracy: 0.8745 - val_loss: 0.5781 - val_accuracy: 0.8212 - lr: 5.0000e-04
Epoch 22/30
707/708 [============================>.] - ETA: 0s - loss: 0.3414 - accuracy: 0.8769
Epoch 22: val_loss improved from 0.57808 to 0.57342, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.3415 - accuracy: 0.8768 - val_loss: 0.5734 - val_accuracy: 0.8329 - lr: 5.0000e-04
Epoch 23/30
708/708 [==============================] - ETA: 0s - loss: 0.3201 - accuracy: 0.8852
Epoch 23: val_loss improved from 0.57342 to 0.56806, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.3201 - accuracy: 0.8852 - val_loss: 0.5681 - val_accuracy: 0.8313 - lr: 5.0000e-04
Epoch 24/30
708/708 [==============================] - ETA: 0s - loss: 0.3036 - accuracy: 0.8944
Epoch 24: val_loss did not improve from 0.56806
708/708 [==============================] - 18s 26ms/step - loss: 0.3036 - accuracy: 0.8944 - val_loss: 0.5714 - val_accuracy: 0.8317 - lr: 5.0000e-04
Epoch 25/30
706/708 [============================>.] - ETA: 0s - loss: 0.2839 - accuracy: 0.9003
Epoch 25: val_loss did not improve from 0.56806
708/708 [==============================] - 18s 26ms/step - loss: 0.2839 - accuracy: 0.9002 - val_loss: 0.5808 - val_accuracy: 0.8333 - lr: 5.0000e-04
Epoch 26/30
706/708 [============================>.] - ETA: 0s - loss: 0.2714 - accuracy: 0.9026
Epoch 26: val_loss did not improve from 0.56806

Epoch 26: ReduceLROnPlateau reducing learning rate to 0.00015811389051842542.
708/708 [==============================] - 18s 26ms/step - loss: 0.2713 - accuracy: 0.9025 - val_loss: 0.5834 - val_accuracy: 0.8353 - lr: 5.0000e-04
Epoch 27/30
706/708 [============================>.] - ETA: 0s - loss: 0.2267 - accuracy: 0.9189
Epoch 27: val_loss did not improve from 0.56806
708/708 [==============================] - 18s 26ms/step - loss: 0.2265 - accuracy: 0.9190 - val_loss: 0.5733 - val_accuracy: 0.8425 - lr: 1.5811e-04
Epoch 28/30
706/708 [============================>.] - ETA: 0s - loss: 0.2006 - accuracy: 0.9290
Epoch 28: val_loss did not improve from 0.56806
708/708 [==============================] - 18s 26ms/step - loss: 0.2006 - accuracy: 0.9289 - val_loss: 0.5730 - val_accuracy: 0.8423 - lr: 1.5811e-04
Epoch 29/30
707/708 [============================>.] - ETA: 0s - loss: 0.1969 - accuracy: 0.9299
Epoch 29: val_loss did not improve from 0.56806

Epoch 29: ReduceLROnPlateau reducing learning rate to 5.0000003198030994e-05.
708/708 [==============================] - 18s 26ms/step - loss: 0.1968 - accuracy: 0.9299 - val_loss: 0.5784 - val_accuracy: 0.8447 - lr: 1.5811e-04
Epoch 30/30
706/708 [============================>.] - ETA: 0s - loss: 0.1796 - accuracy: 0.9374
Epoch 30: val_loss did not improve from 0.56806
708/708 [==============================] - 18s 26ms/step - loss: 0.1797 - accuracy: 0.9374 - val_loss: 0.5856 - val_accuracy: 0.8453 - lr: 5.0000e-05
394/394 [==============================] - 2s 6ms/step - loss: 0.6120 - accuracy: 0.8457
Out[ ]:
[0.6120489835739136, 0.8456892967224121]
Final Combination Results
In [ ]:
plot_model_history(history8, name="Final Combined Model")
Min validation loss: 0.5680626630783081 
Max validation loss: 1.7567416429519653 
Min validation acc: 0.3116805851459503 
Max validation acc: 0.845252275466919
Model 2 vs Final Combined Model
In [ ]:
compare_model_history(history2, history8, name="Model 2 vs Final Combined Model", key1="Model 2", key2="Final Combined Model")
Model 2 validation loss: 0.5889896154403687 
Final Combined Model validation loss: 0.5680626630783081

Model 2 validation accuracy: 0.8458482027053833 
Final Combined Model validation accuracy: 0.845252275466919

Final Combined Model with Data Augmentation

In [ ]:
train_datagen = ImageDataGenerator(
    rotation_range=10, # rotating images randomly from 0 to 180 degrees
    zoom_range = 0.1, # zooming into the image
    width_shift_range=0.1, # horizontally shifting the images
    height_shift_range=0.1, # vertically shifting the images
    horizontal_flip=True, # allows horizontal flipping of images
    vertical_flip=True, # allows vertical flipping of images
    fill_mode='nearest') # replaces the empty area with the nearest pixel values

plot_augmentation_samples(train_datagen)
Data Augmentation Samples has been saved
In [ ]:
model = final_combined_model()

history9 = train_augmented_model(model, train_datagen, 80, 128)
model.evaluate(x_test, y_test)
Epoch 1/80
352/353 [============================>.] - ETA: 0s - loss: 2.2990 - accuracy: 0.1946
Epoch 1: val_loss improved from inf to 2.01496, saving model to best-model.h5
353/353 [==============================] - 18s 48ms/step - loss: 2.2985 - accuracy: 0.1949 - val_loss: 2.0150 - val_accuracy: 0.1561 - lr: 5.0000e-04
Epoch 2/80
352/353 [============================>.] - ETA: 0s - loss: 2.0626 - accuracy: 0.2353
Epoch 2: val_loss improved from 2.01496 to 1.73165, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 2.0623 - accuracy: 0.2353 - val_loss: 1.7317 - val_accuracy: 0.3172 - lr: 5.0000e-04
Epoch 3/80
352/353 [============================>.] - ETA: 0s - loss: 1.9164 - accuracy: 0.2801
Epoch 3: val_loss improved from 1.73165 to 1.64016, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 1.9161 - accuracy: 0.2802 - val_loss: 1.6402 - val_accuracy: 0.3659 - lr: 5.0000e-04
Epoch 4/80
352/353 [============================>.] - ETA: 0s - loss: 1.7677 - accuracy: 0.3395
Epoch 4: val_loss improved from 1.64016 to 1.49275, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.7675 - accuracy: 0.3396 - val_loss: 1.4928 - val_accuracy: 0.4327 - lr: 5.0000e-04
Epoch 5/80
352/353 [============================>.] - ETA: 0s - loss: 1.6103 - accuracy: 0.3955
Epoch 5: val_loss improved from 1.49275 to 1.36513, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.6103 - accuracy: 0.3955 - val_loss: 1.3651 - val_accuracy: 0.4831 - lr: 5.0000e-04
Epoch 6/80
352/353 [============================>.] - ETA: 0s - loss: 1.4845 - accuracy: 0.4447
Epoch 6: val_loss improved from 1.36513 to 1.33193, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.4841 - accuracy: 0.4449 - val_loss: 1.3319 - val_accuracy: 0.4940 - lr: 5.0000e-04
Epoch 7/80
353/353 [==============================] - ETA: 0s - loss: 1.3909 - accuracy: 0.4761
Epoch 7: val_loss improved from 1.33193 to 1.17264, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.3909 - accuracy: 0.4761 - val_loss: 1.1726 - val_accuracy: 0.5501 - lr: 5.0000e-04
Epoch 8/80
352/353 [============================>.] - ETA: 0s - loss: 1.3007 - accuracy: 0.5100
Epoch 8: val_loss improved from 1.17264 to 1.10067, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.3003 - accuracy: 0.5102 - val_loss: 1.1007 - val_accuracy: 0.5836 - lr: 5.0000e-04
Epoch 9/80
352/353 [============================>.] - ETA: 0s - loss: 1.2339 - accuracy: 0.5345
Epoch 9: val_loss improved from 1.10067 to 1.08392, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.2342 - accuracy: 0.5344 - val_loss: 1.0839 - val_accuracy: 0.5910 - lr: 5.0000e-04
Epoch 10/80
352/353 [============================>.] - ETA: 0s - loss: 1.1794 - accuracy: 0.5553
Epoch 10: val_loss improved from 1.08392 to 1.01805, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.1792 - accuracy: 0.5554 - val_loss: 1.0181 - val_accuracy: 0.6150 - lr: 5.0000e-04
Epoch 11/80
353/353 [==============================] - ETA: 0s - loss: 1.1296 - accuracy: 0.5733
Epoch 11: val_loss improved from 1.01805 to 1.01225, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.1296 - accuracy: 0.5733 - val_loss: 1.0123 - val_accuracy: 0.6182 - lr: 5.0000e-04
Epoch 12/80
352/353 [============================>.] - ETA: 0s - loss: 1.0840 - accuracy: 0.5930
Epoch 12: val_loss improved from 1.01225 to 0.92594, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.0841 - accuracy: 0.5930 - val_loss: 0.9259 - val_accuracy: 0.6490 - lr: 5.0000e-04
Epoch 13/80
352/353 [============================>.] - ETA: 0s - loss: 1.0420 - accuracy: 0.6080
Epoch 13: val_loss improved from 0.92594 to 0.90837, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.0422 - accuracy: 0.6079 - val_loss: 0.9084 - val_accuracy: 0.6498 - lr: 5.0000e-04
Epoch 14/80
352/353 [============================>.] - ETA: 0s - loss: 1.0128 - accuracy: 0.6202
Epoch 14: val_loss improved from 0.90837 to 0.88112, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 1.0125 - accuracy: 0.6203 - val_loss: 0.8811 - val_accuracy: 0.6659 - lr: 5.0000e-04
Epoch 15/80
352/353 [============================>.] - ETA: 0s - loss: 0.9844 - accuracy: 0.6321
Epoch 15: val_loss did not improve from 0.88112
353/353 [==============================] - 17s 47ms/step - loss: 0.9841 - accuracy: 0.6320 - val_loss: 0.9076 - val_accuracy: 0.6476 - lr: 5.0000e-04
Epoch 16/80
353/353 [==============================] - ETA: 0s - loss: 0.9539 - accuracy: 0.6432
Epoch 16: val_loss improved from 0.88112 to 0.87470, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.9539 - accuracy: 0.6432 - val_loss: 0.8747 - val_accuracy: 0.6692 - lr: 5.0000e-04
Epoch 17/80
353/353 [==============================] - ETA: 0s - loss: 0.9274 - accuracy: 0.6532
Epoch 17: val_loss improved from 0.87470 to 0.80462, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 0.9274 - accuracy: 0.6532 - val_loss: 0.8046 - val_accuracy: 0.6937 - lr: 5.0000e-04
Epoch 18/80
353/353 [==============================] - ETA: 0s - loss: 0.9037 - accuracy: 0.6609
Epoch 18: val_loss did not improve from 0.80462
353/353 [==============================] - 17s 47ms/step - loss: 0.9037 - accuracy: 0.6609 - val_loss: 0.8267 - val_accuracy: 0.6832 - lr: 5.0000e-04
Epoch 19/80
353/353 [==============================] - ETA: 0s - loss: 0.8782 - accuracy: 0.6686
Epoch 19: val_loss did not improve from 0.80462
353/353 [==============================] - 17s 49ms/step - loss: 0.8782 - accuracy: 0.6686 - val_loss: 0.8285 - val_accuracy: 0.6885 - lr: 5.0000e-04
Epoch 20/80
353/353 [==============================] - ETA: 0s - loss: 0.8548 - accuracy: 0.6797
Epoch 20: val_loss improved from 0.80462 to 0.79782, saving model to best-model.h5
353/353 [==============================] - 18s 52ms/step - loss: 0.8548 - accuracy: 0.6797 - val_loss: 0.7978 - val_accuracy: 0.7034 - lr: 5.0000e-04
Epoch 21/80
353/353 [==============================] - ETA: 0s - loss: 0.8389 - accuracy: 0.6863
Epoch 21: val_loss improved from 0.79782 to 0.79200, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.8389 - accuracy: 0.6863 - val_loss: 0.7920 - val_accuracy: 0.7028 - lr: 5.0000e-04
Epoch 22/80
353/353 [==============================] - ETA: 0s - loss: 0.8217 - accuracy: 0.6922
Epoch 22: val_loss improved from 0.79200 to 0.74942, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 0.8217 - accuracy: 0.6922 - val_loss: 0.7494 - val_accuracy: 0.7149 - lr: 5.0000e-04
Epoch 23/80
352/353 [============================>.] - ETA: 0s - loss: 0.8048 - accuracy: 0.6990
Epoch 23: val_loss improved from 0.74942 to 0.74191, saving model to best-model.h5
353/353 [==============================] - 18s 52ms/step - loss: 0.8046 - accuracy: 0.6991 - val_loss: 0.7419 - val_accuracy: 0.7189 - lr: 5.0000e-04
Epoch 24/80
353/353 [==============================] - ETA: 0s - loss: 0.7847 - accuracy: 0.7069
Epoch 24: val_loss improved from 0.74191 to 0.71948, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.7847 - accuracy: 0.7069 - val_loss: 0.7195 - val_accuracy: 0.7332 - lr: 5.0000e-04
Epoch 25/80
352/353 [============================>.] - ETA: 0s - loss: 0.7719 - accuracy: 0.7149
Epoch 25: val_loss did not improve from 0.71948
353/353 [==============================] - 17s 47ms/step - loss: 0.7722 - accuracy: 0.7148 - val_loss: 0.7429 - val_accuracy: 0.7267 - lr: 5.0000e-04
Epoch 26/80
352/353 [============================>.] - ETA: 0s - loss: 0.7532 - accuracy: 0.7193
Epoch 26: val_loss improved from 0.71948 to 0.71428, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.7534 - accuracy: 0.7194 - val_loss: 0.7143 - val_accuracy: 0.7346 - lr: 5.0000e-04
Epoch 27/80
352/353 [============================>.] - ETA: 0s - loss: 0.7440 - accuracy: 0.7222
Epoch 27: val_loss improved from 0.71428 to 0.70860, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.7440 - accuracy: 0.7222 - val_loss: 0.7086 - val_accuracy: 0.7414 - lr: 5.0000e-04
Epoch 28/80
353/353 [==============================] - ETA: 0s - loss: 0.7244 - accuracy: 0.7311
Epoch 28: val_loss improved from 0.70860 to 0.69429, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.7244 - accuracy: 0.7311 - val_loss: 0.6943 - val_accuracy: 0.7426 - lr: 5.0000e-04
Epoch 29/80
352/353 [============================>.] - ETA: 0s - loss: 0.7131 - accuracy: 0.7390
Epoch 29: val_loss did not improve from 0.69429
353/353 [==============================] - 17s 47ms/step - loss: 0.7130 - accuracy: 0.7391 - val_loss: 0.6948 - val_accuracy: 0.7455 - lr: 5.0000e-04
Epoch 30/80
352/353 [============================>.] - ETA: 0s - loss: 0.7028 - accuracy: 0.7398
Epoch 30: val_loss improved from 0.69429 to 0.67519, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.7026 - accuracy: 0.7398 - val_loss: 0.6752 - val_accuracy: 0.7501 - lr: 5.0000e-04
Epoch 31/80
353/353 [==============================] - ETA: 0s - loss: 0.6849 - accuracy: 0.7454
Epoch 31: val_loss improved from 0.67519 to 0.66594, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 0.6849 - accuracy: 0.7454 - val_loss: 0.6659 - val_accuracy: 0.7604 - lr: 5.0000e-04
Epoch 32/80
353/353 [==============================] - ETA: 0s - loss: 0.6769 - accuracy: 0.7512
Epoch 32: val_loss did not improve from 0.66594
353/353 [==============================] - 17s 47ms/step - loss: 0.6769 - accuracy: 0.7512 - val_loss: 0.6935 - val_accuracy: 0.7465 - lr: 5.0000e-04
Epoch 33/80
353/353 [==============================] - ETA: 0s - loss: 0.6687 - accuracy: 0.7521
Epoch 33: val_loss did not improve from 0.66594
353/353 [==============================] - 17s 47ms/step - loss: 0.6687 - accuracy: 0.7521 - val_loss: 0.7284 - val_accuracy: 0.7330 - lr: 5.0000e-04
Epoch 34/80
352/353 [============================>.] - ETA: 0s - loss: 0.6512 - accuracy: 0.7608
Epoch 34: val_loss improved from 0.66594 to 0.63767, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.6517 - accuracy: 0.7606 - val_loss: 0.6377 - val_accuracy: 0.7737 - lr: 5.0000e-04
Epoch 35/80
352/353 [============================>.] - ETA: 0s - loss: 0.6423 - accuracy: 0.7639
Epoch 35: val_loss did not improve from 0.63767
353/353 [==============================] - 17s 47ms/step - loss: 0.6426 - accuracy: 0.7639 - val_loss: 0.6669 - val_accuracy: 0.7640 - lr: 5.0000e-04
Epoch 36/80
353/353 [==============================] - ETA: 0s - loss: 0.6342 - accuracy: 0.7652
Epoch 36: val_loss did not improve from 0.63767
353/353 [==============================] - 16s 47ms/step - loss: 0.6342 - accuracy: 0.7652 - val_loss: 0.6520 - val_accuracy: 0.7692 - lr: 5.0000e-04
Epoch 37/80
352/353 [============================>.] - ETA: 0s - loss: 0.6294 - accuracy: 0.7706
Epoch 37: val_loss improved from 0.63767 to 0.62739, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.6292 - accuracy: 0.7706 - val_loss: 0.6274 - val_accuracy: 0.7769 - lr: 5.0000e-04
Epoch 38/80
353/353 [==============================] - ETA: 0s - loss: 0.6098 - accuracy: 0.7767
Epoch 38: val_loss did not improve from 0.62739
353/353 [==============================] - 17s 47ms/step - loss: 0.6098 - accuracy: 0.7767 - val_loss: 0.6408 - val_accuracy: 0.7731 - lr: 5.0000e-04
Epoch 39/80
353/353 [==============================] - ETA: 0s - loss: 0.6062 - accuracy: 0.7773
Epoch 39: val_loss improved from 0.62739 to 0.61620, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 0.6062 - accuracy: 0.7773 - val_loss: 0.6162 - val_accuracy: 0.7827 - lr: 5.0000e-04
Epoch 40/80
353/353 [==============================] - ETA: 0s - loss: 0.5910 - accuracy: 0.7863
Epoch 40: val_loss did not improve from 0.61620
353/353 [==============================] - 17s 47ms/step - loss: 0.5910 - accuracy: 0.7863 - val_loss: 0.6281 - val_accuracy: 0.7835 - lr: 5.0000e-04
Epoch 41/80
352/353 [============================>.] - ETA: 0s - loss: 0.5758 - accuracy: 0.7895
Epoch 41: val_loss improved from 0.61620 to 0.61442, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 0.5757 - accuracy: 0.7895 - val_loss: 0.6144 - val_accuracy: 0.7878 - lr: 5.0000e-04
Epoch 42/80
352/353 [============================>.] - ETA: 0s - loss: 0.5774 - accuracy: 0.7897
Epoch 42: val_loss did not improve from 0.61442
353/353 [==============================] - 17s 47ms/step - loss: 0.5775 - accuracy: 0.7896 - val_loss: 0.6240 - val_accuracy: 0.7833 - lr: 5.0000e-04
Epoch 43/80
353/353 [==============================] - ETA: 0s - loss: 0.5667 - accuracy: 0.7936
Epoch 43: val_loss improved from 0.61442 to 0.60832, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.5667 - accuracy: 0.7936 - val_loss: 0.6083 - val_accuracy: 0.7912 - lr: 5.0000e-04
Epoch 44/80
352/353 [============================>.] - ETA: 0s - loss: 0.5603 - accuracy: 0.7945
Epoch 44: val_loss did not improve from 0.60832
353/353 [==============================] - 17s 47ms/step - loss: 0.5600 - accuracy: 0.7946 - val_loss: 0.6162 - val_accuracy: 0.7835 - lr: 5.0000e-04
Epoch 45/80
353/353 [==============================] - ETA: 0s - loss: 0.5484 - accuracy: 0.8005
Epoch 45: val_loss improved from 0.60832 to 0.58878, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.5484 - accuracy: 0.8005 - val_loss: 0.5888 - val_accuracy: 0.7988 - lr: 5.0000e-04
Epoch 46/80
353/353 [==============================] - ETA: 0s - loss: 0.5428 - accuracy: 0.8021
Epoch 46: val_loss improved from 0.58878 to 0.57702, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 0.5428 - accuracy: 0.8021 - val_loss: 0.5770 - val_accuracy: 0.8014 - lr: 5.0000e-04
Epoch 47/80
352/353 [============================>.] - ETA: 0s - loss: 0.5332 - accuracy: 0.8066
Epoch 47: val_loss did not improve from 0.57702
353/353 [==============================] - 17s 47ms/step - loss: 0.5329 - accuracy: 0.8067 - val_loss: 0.5830 - val_accuracy: 0.8049 - lr: 5.0000e-04
Epoch 48/80
352/353 [============================>.] - ETA: 0s - loss: 0.5368 - accuracy: 0.8080
Epoch 48: val_loss did not improve from 0.57702
353/353 [==============================] - 17s 47ms/step - loss: 0.5371 - accuracy: 0.8079 - val_loss: 0.5834 - val_accuracy: 0.8063 - lr: 5.0000e-04
Epoch 49/80
352/353 [============================>.] - ETA: 0s - loss: 0.5211 - accuracy: 0.8126
Epoch 49: val_loss did not improve from 0.57702

Epoch 49: ReduceLROnPlateau reducing learning rate to 0.00010000000474974513.
353/353 [==============================] - 17s 48ms/step - loss: 0.5212 - accuracy: 0.8126 - val_loss: 0.5917 - val_accuracy: 0.8015 - lr: 5.0000e-04
Epoch 50/80
352/353 [============================>.] - ETA: 0s - loss: 0.4957 - accuracy: 0.8201
Epoch 50: val_loss improved from 0.57702 to 0.55834, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.4958 - accuracy: 0.8199 - val_loss: 0.5583 - val_accuracy: 0.8065 - lr: 1.0000e-04
Epoch 51/80
353/353 [==============================] - ETA: 0s - loss: 0.4757 - accuracy: 0.8284
Epoch 51: val_loss improved from 0.55834 to 0.55793, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.4757 - accuracy: 0.8284 - val_loss: 0.5579 - val_accuracy: 0.8115 - lr: 1.0000e-04
Epoch 52/80
352/353 [============================>.] - ETA: 0s - loss: 0.4715 - accuracy: 0.8307
Epoch 52: val_loss improved from 0.55793 to 0.54574, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.4712 - accuracy: 0.8308 - val_loss: 0.5457 - val_accuracy: 0.8170 - lr: 1.0000e-04
Epoch 53/80
352/353 [============================>.] - ETA: 0s - loss: 0.4669 - accuracy: 0.8331
Epoch 53: val_loss did not improve from 0.54574
353/353 [==============================] - 17s 47ms/step - loss: 0.4666 - accuracy: 0.8331 - val_loss: 0.5460 - val_accuracy: 0.8182 - lr: 1.0000e-04
Epoch 54/80
352/353 [============================>.] - ETA: 0s - loss: 0.4595 - accuracy: 0.8341
Epoch 54: val_loss did not improve from 0.54574
353/353 [==============================] - 17s 47ms/step - loss: 0.4596 - accuracy: 0.8341 - val_loss: 0.5543 - val_accuracy: 0.8190 - lr: 1.0000e-04
Epoch 55/80
353/353 [==============================] - ETA: 0s - loss: 0.4559 - accuracy: 0.8339
Epoch 55: val_loss did not improve from 0.54574

Epoch 55: ReduceLROnPlateau reducing learning rate to 2.0000000949949027e-05.
353/353 [==============================] - 17s 47ms/step - loss: 0.4559 - accuracy: 0.8339 - val_loss: 0.5494 - val_accuracy: 0.8184 - lr: 1.0000e-04
Epoch 56/80
353/353 [==============================] - ETA: 0s - loss: 0.4493 - accuracy: 0.8379
Epoch 56: val_loss did not improve from 0.54574
353/353 [==============================] - 17s 47ms/step - loss: 0.4493 - accuracy: 0.8379 - val_loss: 0.5466 - val_accuracy: 0.8188 - lr: 2.0000e-05
Epoch 57/80
353/353 [==============================] - ETA: 0s - loss: 0.4506 - accuracy: 0.8391
Epoch 57: val_loss did not improve from 0.54574
353/353 [==============================] - 19s 53ms/step - loss: 0.4506 - accuracy: 0.8391 - val_loss: 0.5473 - val_accuracy: 0.8198 - lr: 2.0000e-05
Epoch 58/80
352/353 [============================>.] - ETA: 0s - loss: 0.4419 - accuracy: 0.8412
Epoch 58: val_loss improved from 0.54574 to 0.54567, saving model to best-model.h5

Epoch 58: ReduceLROnPlateau reducing learning rate to 4.000000262749381e-06.
353/353 [==============================] - 18s 52ms/step - loss: 0.4424 - accuracy: 0.8411 - val_loss: 0.5457 - val_accuracy: 0.8196 - lr: 2.0000e-05
Epoch 59/80
353/353 [==============================] - ETA: 0s - loss: 0.4435 - accuracy: 0.8402
Epoch 59: val_loss did not improve from 0.54567
353/353 [==============================] - 19s 52ms/step - loss: 0.4435 - accuracy: 0.8402 - val_loss: 0.5461 - val_accuracy: 0.8212 - lr: 4.0000e-06
Epoch 60/80
353/353 [==============================] - ETA: 0s - loss: 0.4487 - accuracy: 0.8385
Epoch 60: val_loss did not improve from 0.54567
353/353 [==============================] - 19s 54ms/step - loss: 0.4487 - accuracy: 0.8385 - val_loss: 0.5457 - val_accuracy: 0.8210 - lr: 4.0000e-06
Epoch 61/80
353/353 [==============================] - ETA: 0s - loss: 0.4421 - accuracy: 0.8421
Epoch 61: val_loss improved from 0.54567 to 0.54562, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.4421 - accuracy: 0.8421 - val_loss: 0.5456 - val_accuracy: 0.8208 - lr: 4.0000e-06
Epoch 62/80
352/353 [============================>.] - ETA: 0s - loss: 0.4382 - accuracy: 0.8401Restoring model weights from the end of the best epoch: 59.

Epoch 62: val_loss improved from 0.54562 to 0.54542, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 0.4379 - accuracy: 0.8402 - val_loss: 0.5454 - val_accuracy: 0.8212 - lr: 4.0000e-06
Epoch 62: early stopping
394/394 [==============================] - 2s 6ms/step - loss: 0.5669 - accuracy: 0.8199
Out[ ]:
[0.5668871402740479, 0.8199443817138672]
Data Augmentation Results
In [ ]:
plot_model_history(history9, name="Final Combined Model with Data Augmentation")
Min validation loss: 0.5454151034355164 
Max validation loss: 2.0149643421173096 
Min validation acc: 0.15613825619220734 
Max validation acc: 0.8212157487869263

Final Model

In [46]:
def final_model():
  model = models.Sequential()

  # 1st convolutional layer
  model.add(layers.Conv2D(64, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=(x_train.shape[1:])))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))

  # 2nd convolutional layer
  model.add(layers.Conv2D(128, kernel_size=5, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))

  # 3rd convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.3))

  # 4th convolutional layer
  model.add(layers.Conv2D(512, kernel_size=3, strides=1, padding='same', activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.AveragePooling2D((2, 2)))
  model.add(layers.Dropout(0.35))
  model.add(layers.Flatten())

  # 1st fully connected dense layer
  model.add(layers.Dense(256, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.3))

  # 2nd fully connected dense layer
  model.add(layers.Dense(512, activation='relu'))
  model.add(layers.BatchNormalization())
  model.add(layers.Dropout(0.3))

  # final dense layer with number of classes
  model.add(layers.Dense(7, activation='softmax'))

  # compile the model
  model.compile(optimizer=optimizers.Adamax(learning_rate=0.0005, beta_1=0.9, beta_2=0.999), loss='categorical_crossentropy', metrics=['accuracy'])
  return model
In [47]:
model = final_model()
save_figure("Final Model Architecture")
plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True)
Final Model Architecture has been saved
Out[47]:
<Figure size 432x288 with 0 Axes>
In [48]:
model.summary()
Model: "sequential_7"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d_29 (Conv2D)          (None, 48, 48, 64)        640       
                                                                 
 batch_normalization_36 (Bat  (None, 48, 48, 64)       256       
 chNormalization)                                                
                                                                 
 average_pooling2d_8 (Averag  (None, 24, 24, 64)       0         
 ePooling2D)                                                     
                                                                 
 dropout_36 (Dropout)        (None, 24, 24, 64)        0         
                                                                 
 conv2d_30 (Conv2D)          (None, 24, 24, 128)       204928    
                                                                 
 batch_normalization_37 (Bat  (None, 24, 24, 128)      512       
 chNormalization)                                                
                                                                 
 average_pooling2d_9 (Averag  (None, 12, 12, 128)      0         
 ePooling2D)                                                     
                                                                 
 dropout_37 (Dropout)        (None, 12, 12, 128)       0         
                                                                 
 conv2d_31 (Conv2D)          (None, 12, 12, 512)       590336    
                                                                 
 batch_normalization_38 (Bat  (None, 12, 12, 512)      2048      
 chNormalization)                                                
                                                                 
 average_pooling2d_10 (Avera  (None, 6, 6, 512)        0         
 gePooling2D)                                                    
                                                                 
 dropout_38 (Dropout)        (None, 6, 6, 512)         0         
                                                                 
 conv2d_32 (Conv2D)          (None, 6, 6, 512)         2359808   
                                                                 
 batch_normalization_39 (Bat  (None, 6, 6, 512)        2048      
 chNormalization)                                                
                                                                 
 average_pooling2d_11 (Avera  (None, 3, 3, 512)        0         
 gePooling2D)                                                    
                                                                 
 dropout_39 (Dropout)        (None, 3, 3, 512)         0         
                                                                 
 flatten_7 (Flatten)         (None, 4608)              0         
                                                                 
 dense_20 (Dense)            (None, 256)               1179904   
                                                                 
 batch_normalization_40 (Bat  (None, 256)              1024      
 chNormalization)                                                
                                                                 
 dropout_40 (Dropout)        (None, 256)               0         
                                                                 
 dense_21 (Dense)            (None, 512)               131584    
                                                                 
 batch_normalization_41 (Bat  (None, 512)              2048      
 chNormalization)                                                
                                                                 
 dropout_41 (Dropout)        (None, 512)               0         
                                                                 
 dense_22 (Dense)            (None, 7)                 3591      
                                                                 
=================================================================
Total params: 4,478,727
Trainable params: 4,474,759
Non-trainable params: 3,968
_________________________________________________________________
In [ ]:
history10 = train_model(model, 30, 64)
model.evaluate(x_test, y_test)
Epoch 1/30
706/708 [============================>.] - ETA: 0s - loss: 2.1827 - accuracy: 0.2345
Epoch 1: val_loss improved from inf to 1.72933, saving model to best-model.h5
708/708 [==============================] - 20s 26ms/step - loss: 2.1823 - accuracy: 0.2346 - val_loss: 1.7293 - val_accuracy: 0.3385 - lr: 5.0000e-04
Epoch 2/30
707/708 [============================>.] - ETA: 0s - loss: 1.7687 - accuracy: 0.3559
Epoch 2: val_loss improved from 1.72933 to 1.42490, saving model to best-model.h5
708/708 [==============================] - 18s 26ms/step - loss: 1.7684 - accuracy: 0.3560 - val_loss: 1.4249 - val_accuracy: 0.4495 - lr: 5.0000e-04
Epoch 3/30
707/708 [============================>.] - ETA: 0s - loss: 1.4954 - accuracy: 0.4462
Epoch 3: val_loss improved from 1.42490 to 1.31612, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.4952 - accuracy: 0.4463 - val_loss: 1.3161 - val_accuracy: 0.5052 - lr: 5.0000e-04
Epoch 4/30
707/708 [============================>.] - ETA: 0s - loss: 1.3044 - accuracy: 0.5140
Epoch 4: val_loss improved from 1.31612 to 1.14273, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.3041 - accuracy: 0.5141 - val_loss: 1.1427 - val_accuracy: 0.5598 - lr: 5.0000e-04
Epoch 5/30
707/708 [============================>.] - ETA: 0s - loss: 1.1617 - accuracy: 0.5665
Epoch 5: val_loss improved from 1.14273 to 1.08128, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 1.1618 - accuracy: 0.5665 - val_loss: 1.0813 - val_accuracy: 0.5894 - lr: 5.0000e-04
Epoch 6/30
706/708 [============================>.] - ETA: 0s - loss: 1.0592 - accuracy: 0.6032
Epoch 6: val_loss improved from 1.08128 to 0.97144, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 1.0590 - accuracy: 0.6033 - val_loss: 0.9714 - val_accuracy: 0.6299 - lr: 5.0000e-04
Epoch 7/30
706/708 [============================>.] - ETA: 0s - loss: 0.9729 - accuracy: 0.6348
Epoch 7: val_loss improved from 0.97144 to 0.91135, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.9732 - accuracy: 0.6347 - val_loss: 0.9114 - val_accuracy: 0.6567 - lr: 5.0000e-04
Epoch 8/30
707/708 [============================>.] - ETA: 0s - loss: 0.9062 - accuracy: 0.6605
Epoch 8: val_loss improved from 0.91135 to 0.83739, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.9061 - accuracy: 0.6604 - val_loss: 0.8374 - val_accuracy: 0.6772 - lr: 5.0000e-04
Epoch 9/30
706/708 [============================>.] - ETA: 0s - loss: 0.8453 - accuracy: 0.6838
Epoch 9: val_loss improved from 0.83739 to 0.80060, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.8453 - accuracy: 0.6839 - val_loss: 0.8006 - val_accuracy: 0.7014 - lr: 5.0000e-04
Epoch 10/30
707/708 [============================>.] - ETA: 0s - loss: 0.7855 - accuracy: 0.7096
Epoch 10: val_loss improved from 0.80060 to 0.76742, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.7854 - accuracy: 0.7096 - val_loss: 0.7674 - val_accuracy: 0.7137 - lr: 5.0000e-04
Epoch 11/30
707/708 [============================>.] - ETA: 0s - loss: 0.7308 - accuracy: 0.7313
Epoch 11: val_loss improved from 0.76742 to 0.71960, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.7308 - accuracy: 0.7312 - val_loss: 0.7196 - val_accuracy: 0.7416 - lr: 5.0000e-04
Epoch 12/30
706/708 [============================>.] - ETA: 0s - loss: 0.6822 - accuracy: 0.7495
Epoch 12: val_loss did not improve from 0.71960
708/708 [==============================] - 19s 26ms/step - loss: 0.6821 - accuracy: 0.7495 - val_loss: 0.7401 - val_accuracy: 0.7342 - lr: 5.0000e-04
Epoch 13/30
707/708 [============================>.] - ETA: 0s - loss: 0.6331 - accuracy: 0.7664
Epoch 13: val_loss improved from 0.71960 to 0.67963, saving model to best-model.h5
708/708 [==============================] - 19s 26ms/step - loss: 0.6330 - accuracy: 0.7664 - val_loss: 0.6796 - val_accuracy: 0.7624 - lr: 5.0000e-04
Epoch 14/30
706/708 [============================>.] - ETA: 0s - loss: 0.5795 - accuracy: 0.7905
Epoch 14: val_loss improved from 0.67963 to 0.66225, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5796 - accuracy: 0.7904 - val_loss: 0.6622 - val_accuracy: 0.7781 - lr: 5.0000e-04
Epoch 15/30
706/708 [============================>.] - ETA: 0s - loss: 0.5429 - accuracy: 0.8048
Epoch 15: val_loss improved from 0.66225 to 0.62798, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.5431 - accuracy: 0.8047 - val_loss: 0.6280 - val_accuracy: 0.7829 - lr: 5.0000e-04
Epoch 16/30
707/708 [============================>.] - ETA: 0s - loss: 0.5053 - accuracy: 0.8187
Epoch 16: val_loss did not improve from 0.62798
708/708 [==============================] - 19s 26ms/step - loss: 0.5053 - accuracy: 0.8188 - val_loss: 0.6430 - val_accuracy: 0.7870 - lr: 5.0000e-04
Epoch 17/30
707/708 [============================>.] - ETA: 0s - loss: 0.4703 - accuracy: 0.8307
Epoch 17: val_loss improved from 0.62798 to 0.61038, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.4705 - accuracy: 0.8307 - val_loss: 0.6104 - val_accuracy: 0.8049 - lr: 5.0000e-04
Epoch 18/30
707/708 [============================>.] - ETA: 0s - loss: 0.4470 - accuracy: 0.8394
Epoch 18: val_loss did not improve from 0.61038
708/708 [==============================] - 19s 26ms/step - loss: 0.4469 - accuracy: 0.8394 - val_loss: 0.6176 - val_accuracy: 0.8023 - lr: 5.0000e-04
Epoch 19/30
707/708 [============================>.] - ETA: 0s - loss: 0.4152 - accuracy: 0.8506
Epoch 19: val_loss improved from 0.61038 to 0.59460, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.4151 - accuracy: 0.8506 - val_loss: 0.5946 - val_accuracy: 0.8073 - lr: 5.0000e-04
Epoch 20/30
707/708 [============================>.] - ETA: 0s - loss: 0.3914 - accuracy: 0.8594
Epoch 20: val_loss did not improve from 0.59460
708/708 [==============================] - 19s 26ms/step - loss: 0.3912 - accuracy: 0.8594 - val_loss: 0.6092 - val_accuracy: 0.8127 - lr: 5.0000e-04
Epoch 21/30
707/708 [============================>.] - ETA: 0s - loss: 0.3671 - accuracy: 0.8684
Epoch 21: val_loss did not improve from 0.59460
708/708 [==============================] - 19s 26ms/step - loss: 0.3673 - accuracy: 0.8683 - val_loss: 0.6292 - val_accuracy: 0.8159 - lr: 5.0000e-04
Epoch 22/30
707/708 [============================>.] - ETA: 0s - loss: 0.3412 - accuracy: 0.8792
Epoch 22: val_loss did not improve from 0.59460

Epoch 22: ReduceLROnPlateau reducing learning rate to 0.00015811389051842542.
708/708 [==============================] - 19s 26ms/step - loss: 0.3411 - accuracy: 0.8793 - val_loss: 0.6189 - val_accuracy: 0.8161 - lr: 5.0000e-04
Epoch 23/30
707/708 [============================>.] - ETA: 0s - loss: 0.2853 - accuracy: 0.8980
Epoch 23: val_loss improved from 0.59460 to 0.59021, saving model to best-model.h5
708/708 [==============================] - 19s 27ms/step - loss: 0.2853 - accuracy: 0.8980 - val_loss: 0.5902 - val_accuracy: 0.8304 - lr: 1.5811e-04
Epoch 24/30
706/708 [============================>.] - ETA: 0s - loss: 0.2631 - accuracy: 0.9079
Epoch 24: val_loss did not improve from 0.59021
708/708 [==============================] - 19s 26ms/step - loss: 0.2633 - accuracy: 0.9078 - val_loss: 0.5907 - val_accuracy: 0.8306 - lr: 1.5811e-04
Epoch 25/30
706/708 [============================>.] - ETA: 0s - loss: 0.2465 - accuracy: 0.9132
Epoch 25: val_loss did not improve from 0.59021
708/708 [==============================] - 19s 26ms/step - loss: 0.2464 - accuracy: 0.9133 - val_loss: 0.5942 - val_accuracy: 0.8325 - lr: 1.5811e-04
Epoch 26/30
706/708 [============================>.] - ETA: 0s - loss: 0.2339 - accuracy: 0.9190
Epoch 26: val_loss did not improve from 0.59021

Epoch 26: ReduceLROnPlateau reducing learning rate to 5.0000003198030994e-05.
708/708 [==============================] - 19s 26ms/step - loss: 0.2339 - accuracy: 0.9189 - val_loss: 0.5952 - val_accuracy: 0.8329 - lr: 1.5811e-04
Epoch 27/30
708/708 [==============================] - ETA: 0s - loss: 0.2163 - accuracy: 0.9242
Epoch 27: val_loss did not improve from 0.59021
708/708 [==============================] - 19s 26ms/step - loss: 0.2163 - accuracy: 0.9242 - val_loss: 0.5976 - val_accuracy: 0.8335 - lr: 5.0000e-05
Epoch 28/30
707/708 [============================>.] - ETA: 0s - loss: 0.2110 - accuracy: 0.9256
Epoch 28: val_loss did not improve from 0.59021
708/708 [==============================] - 19s 26ms/step - loss: 0.2111 - accuracy: 0.9257 - val_loss: 0.6002 - val_accuracy: 0.8331 - lr: 5.0000e-05
Epoch 29/30
707/708 [============================>.] - ETA: 0s - loss: 0.2089 - accuracy: 0.9263
Epoch 29: val_loss did not improve from 0.59021

Epoch 29: ReduceLROnPlateau reducing learning rate to 1.5811389051842542e-05.
708/708 [==============================] - 19s 26ms/step - loss: 0.2089 - accuracy: 0.9263 - val_loss: 0.6052 - val_accuracy: 0.8345 - lr: 5.0000e-05
Epoch 30/30
706/708 [============================>.] - ETA: 0s - loss: 0.2001 - accuracy: 0.9296
Epoch 30: val_loss did not improve from 0.59021
708/708 [==============================] - 19s 26ms/step - loss: 0.2001 - accuracy: 0.9295 - val_loss: 0.6010 - val_accuracy: 0.8359 - lr: 1.5811e-05
394/394 [==============================] - 2s 6ms/step - loss: 0.6067 - accuracy: 0.8408
Out[ ]:
[0.6066526174545288, 0.8407627940177917]
In [ ]:
model.save('final-model.h5', overwrite=True)

Final Model with Data Augmentation

In [ ]:
train_datagen = ImageDataGenerator(
    rotation_range=10, # rotating images randomly from 0 to 180 degrees
    zoom_range = 0.1, # zooming into the image
    width_shift_range=0.1, # horizontally shifting the images
    height_shift_range=0.1, # vertically shifting the images
    horizontal_flip=False, # doesn't allow horizontal flipping of images
    vertical_flip=False, # doesn't allow vertical flipping of images
    fill_mode='nearest') # replaces the empty area with the nearest pixel values

plot_augmentation_samples(train_datagen) 
Data Augmentation Samples has been saved
In [ ]:
model = final_model()

history11 = train_augmented_model(model, train_datagen, 80, 128)
model.evaluate(x_test, y_test)
Epoch 1/80
352/353 [============================>.] - ETA: 0s - loss: 2.3058 - accuracy: 0.1922
Epoch 1: val_loss improved from inf to 1.95658, saving model to best-model.h5
353/353 [==============================] - 30s 53ms/step - loss: 2.3053 - accuracy: 0.1923 - val_loss: 1.9566 - val_accuracy: 0.1522 - lr: 5.0000e-04
Epoch 2/80
352/353 [============================>.] - ETA: 0s - loss: 2.0774 - accuracy: 0.2315
Epoch 2: val_loss improved from 1.95658 to 1.76976, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 2.0771 - accuracy: 0.2316 - val_loss: 1.7698 - val_accuracy: 0.3101 - lr: 5.0000e-04
Epoch 3/80
352/353 [============================>.] - ETA: 0s - loss: 1.9431 - accuracy: 0.2733
Epoch 3: val_loss improved from 1.76976 to 1.61022, saving model to best-model.h5
353/353 [==============================] - 17s 47ms/step - loss: 1.9431 - accuracy: 0.2732 - val_loss: 1.6102 - val_accuracy: 0.3834 - lr: 5.0000e-04
Epoch 4/80
353/353 [==============================] - ETA: 0s - loss: 1.7913 - accuracy: 0.3304
Epoch 4: val_loss improved from 1.61022 to 1.52418, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.7913 - accuracy: 0.3304 - val_loss: 1.5242 - val_accuracy: 0.4132 - lr: 5.0000e-04
Epoch 5/80
352/353 [============================>.] - ETA: 0s - loss: 1.6502 - accuracy: 0.3821
Epoch 5: val_loss improved from 1.52418 to 1.40886, saving model to best-model.h5
353/353 [==============================] - 17s 48ms/step - loss: 1.6503 - accuracy: 0.3820 - val_loss: 1.4089 - val_accuracy: 0.4716 - lr: 5.0000e-04
Epoch 6/80
353/353 [==============================] - ETA: 0s - loss: 1.5310 - accuracy: 0.4280
Epoch 6: val_loss improved from 1.40886 to 1.30394, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.5310 - accuracy: 0.4280 - val_loss: 1.3039 - val_accuracy: 0.5077 - lr: 5.0000e-04
Epoch 7/80
352/353 [============================>.] - ETA: 0s - loss: 1.4229 - accuracy: 0.4687
Epoch 7: val_loss improved from 1.30394 to 1.20467, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.4225 - accuracy: 0.4689 - val_loss: 1.2047 - val_accuracy: 0.5397 - lr: 5.0000e-04
Epoch 8/80
353/353 [==============================] - ETA: 0s - loss: 1.3379 - accuracy: 0.4969
Epoch 8: val_loss improved from 1.20467 to 1.12551, saving model to best-model.h5
353/353 [==============================] - 18s 50ms/step - loss: 1.3379 - accuracy: 0.4969 - val_loss: 1.1255 - val_accuracy: 0.5755 - lr: 5.0000e-04
Epoch 9/80
353/353 [==============================] - ETA: 0s - loss: 1.2678 - accuracy: 0.5248
Epoch 9: val_loss improved from 1.12551 to 1.06170, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.2678 - accuracy: 0.5248 - val_loss: 1.0617 - val_accuracy: 0.5975 - lr: 5.0000e-04
Epoch 10/80
352/353 [============================>.] - ETA: 0s - loss: 1.2087 - accuracy: 0.5457
Epoch 10: val_loss did not improve from 1.06170
353/353 [==============================] - 17s 48ms/step - loss: 1.2087 - accuracy: 0.5457 - val_loss: 1.1292 - val_accuracy: 0.5805 - lr: 5.0000e-04
Epoch 11/80
352/353 [============================>.] - ETA: 0s - loss: 1.1561 - accuracy: 0.5654
Epoch 11: val_loss improved from 1.06170 to 0.98079, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.1564 - accuracy: 0.5653 - val_loss: 0.9808 - val_accuracy: 0.6240 - lr: 5.0000e-04
Epoch 12/80
353/353 [==============================] - ETA: 0s - loss: 1.1107 - accuracy: 0.5822
Epoch 12: val_loss improved from 0.98079 to 0.95996, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.1107 - accuracy: 0.5822 - val_loss: 0.9600 - val_accuracy: 0.6299 - lr: 5.0000e-04
Epoch 13/80
353/353 [==============================] - ETA: 0s - loss: 1.0748 - accuracy: 0.5941
Epoch 13: val_loss improved from 0.95996 to 0.94190, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.0748 - accuracy: 0.5941 - val_loss: 0.9419 - val_accuracy: 0.6347 - lr: 5.0000e-04
Epoch 14/80
353/353 [==============================] - ETA: 0s - loss: 1.0377 - accuracy: 0.6087
Epoch 14: val_loss improved from 0.94190 to 0.88872, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 1.0377 - accuracy: 0.6087 - val_loss: 0.8887 - val_accuracy: 0.6563 - lr: 5.0000e-04
Epoch 15/80
352/353 [============================>.] - ETA: 0s - loss: 1.0084 - accuracy: 0.6194
Epoch 15: val_loss did not improve from 0.88872
353/353 [==============================] - 17s 48ms/step - loss: 1.0081 - accuracy: 0.6193 - val_loss: 0.8945 - val_accuracy: 0.6542 - lr: 5.0000e-04
Epoch 16/80
352/353 [============================>.] - ETA: 0s - loss: 0.9744 - accuracy: 0.6353
Epoch 16: val_loss improved from 0.88872 to 0.87977, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.9742 - accuracy: 0.6354 - val_loss: 0.8798 - val_accuracy: 0.6593 - lr: 5.0000e-04
Epoch 17/80
352/353 [============================>.] - ETA: 0s - loss: 0.9514 - accuracy: 0.6422
Epoch 17: val_loss improved from 0.87977 to 0.83846, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.9517 - accuracy: 0.6420 - val_loss: 0.8385 - val_accuracy: 0.6814 - lr: 5.0000e-04
Epoch 18/80
353/353 [==============================] - ETA: 0s - loss: 0.9304 - accuracy: 0.6532
Epoch 18: val_loss improved from 0.83846 to 0.83428, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.9304 - accuracy: 0.6532 - val_loss: 0.8343 - val_accuracy: 0.6828 - lr: 5.0000e-04
Epoch 19/80
353/353 [==============================] - ETA: 0s - loss: 0.9040 - accuracy: 0.6589
Epoch 19: val_loss improved from 0.83428 to 0.80227, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.9040 - accuracy: 0.6589 - val_loss: 0.8023 - val_accuracy: 0.6979 - lr: 5.0000e-04
Epoch 20/80
352/353 [============================>.] - ETA: 0s - loss: 0.8826 - accuracy: 0.6680
Epoch 20: val_loss did not improve from 0.80227
353/353 [==============================] - 17s 49ms/step - loss: 0.8823 - accuracy: 0.6682 - val_loss: 0.8178 - val_accuracy: 0.6885 - lr: 5.0000e-04
Epoch 21/80
353/353 [==============================] - ETA: 0s - loss: 0.8669 - accuracy: 0.6785
Epoch 21: val_loss improved from 0.80227 to 0.78965, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.8669 - accuracy: 0.6785 - val_loss: 0.7897 - val_accuracy: 0.6983 - lr: 5.0000e-04
Epoch 22/80
352/353 [============================>.] - ETA: 0s - loss: 0.8434 - accuracy: 0.6842
Epoch 22: val_loss improved from 0.78965 to 0.76581, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.8434 - accuracy: 0.6843 - val_loss: 0.7658 - val_accuracy: 0.7096 - lr: 5.0000e-04
Epoch 23/80
352/353 [============================>.] - ETA: 0s - loss: 0.8268 - accuracy: 0.6914
Epoch 23: val_loss did not improve from 0.76581
353/353 [==============================] - 17s 49ms/step - loss: 0.8271 - accuracy: 0.6912 - val_loss: 0.7744 - val_accuracy: 0.7076 - lr: 5.0000e-04
Epoch 24/80
352/353 [============================>.] - ETA: 0s - loss: 0.8137 - accuracy: 0.6956
Epoch 24: val_loss improved from 0.76581 to 0.74595, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.8136 - accuracy: 0.6957 - val_loss: 0.7459 - val_accuracy: 0.7133 - lr: 5.0000e-04
Epoch 25/80
353/353 [==============================] - ETA: 0s - loss: 0.7925 - accuracy: 0.7040
Epoch 25: val_loss improved from 0.74595 to 0.73900, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.7925 - accuracy: 0.7040 - val_loss: 0.7390 - val_accuracy: 0.7239 - lr: 5.0000e-04
Epoch 26/80
353/353 [==============================] - ETA: 0s - loss: 0.7817 - accuracy: 0.7080
Epoch 26: val_loss improved from 0.73900 to 0.70486, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.7817 - accuracy: 0.7080 - val_loss: 0.7049 - val_accuracy: 0.7366 - lr: 5.0000e-04
Epoch 27/80
353/353 [==============================] - ETA: 0s - loss: 0.7662 - accuracy: 0.7174
Epoch 27: val_loss did not improve from 0.70486
353/353 [==============================] - 17s 48ms/step - loss: 0.7662 - accuracy: 0.7174 - val_loss: 0.7311 - val_accuracy: 0.7282 - lr: 5.0000e-04
Epoch 28/80
353/353 [==============================] - ETA: 0s - loss: 0.7535 - accuracy: 0.7222
Epoch 28: val_loss improved from 0.70486 to 0.69906, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.7535 - accuracy: 0.7222 - val_loss: 0.6991 - val_accuracy: 0.7412 - lr: 5.0000e-04
Epoch 29/80
353/353 [==============================] - ETA: 0s - loss: 0.7393 - accuracy: 0.7262
Epoch 29: val_loss improved from 0.69906 to 0.67862, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.7393 - accuracy: 0.7262 - val_loss: 0.6786 - val_accuracy: 0.7505 - lr: 5.0000e-04
Epoch 30/80
352/353 [============================>.] - ETA: 0s - loss: 0.7283 - accuracy: 0.7308
Epoch 30: val_loss did not improve from 0.67862
353/353 [==============================] - 17s 49ms/step - loss: 0.7285 - accuracy: 0.7309 - val_loss: 0.6934 - val_accuracy: 0.7477 - lr: 5.0000e-04
Epoch 31/80
353/353 [==============================] - ETA: 0s - loss: 0.7135 - accuracy: 0.7375
Epoch 31: val_loss improved from 0.67862 to 0.66868, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.7135 - accuracy: 0.7375 - val_loss: 0.6687 - val_accuracy: 0.7559 - lr: 5.0000e-04
Epoch 32/80
352/353 [============================>.] - ETA: 0s - loss: 0.7002 - accuracy: 0.7433
Epoch 32: val_loss did not improve from 0.66868
353/353 [==============================] - 17s 48ms/step - loss: 0.7001 - accuracy: 0.7433 - val_loss: 0.6718 - val_accuracy: 0.7553 - lr: 5.0000e-04
Epoch 33/80
352/353 [============================>.] - ETA: 0s - loss: 0.6916 - accuracy: 0.7460
Epoch 33: val_loss did not improve from 0.66868
353/353 [==============================] - 17s 48ms/step - loss: 0.6917 - accuracy: 0.7459 - val_loss: 0.6844 - val_accuracy: 0.7497 - lr: 5.0000e-04
Epoch 34/80
353/353 [==============================] - ETA: 0s - loss: 0.6759 - accuracy: 0.7500
Epoch 34: val_loss improved from 0.66868 to 0.66164, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.6759 - accuracy: 0.7500 - val_loss: 0.6616 - val_accuracy: 0.7628 - lr: 5.0000e-04
Epoch 35/80
352/353 [============================>.] - ETA: 0s - loss: 0.6674 - accuracy: 0.7563
Epoch 35: val_loss did not improve from 0.66164
353/353 [==============================] - 17s 48ms/step - loss: 0.6674 - accuracy: 0.7563 - val_loss: 0.6646 - val_accuracy: 0.7569 - lr: 5.0000e-04
Epoch 36/80
353/353 [==============================] - ETA: 0s - loss: 0.6583 - accuracy: 0.7579
Epoch 36: val_loss did not improve from 0.66164
353/353 [==============================] - 17s 48ms/step - loss: 0.6583 - accuracy: 0.7579 - val_loss: 0.6658 - val_accuracy: 0.7640 - lr: 5.0000e-04
Epoch 37/80
352/353 [============================>.] - ETA: 0s - loss: 0.6486 - accuracy: 0.7610
Epoch 37: val_loss improved from 0.66164 to 0.65705, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.6487 - accuracy: 0.7609 - val_loss: 0.6571 - val_accuracy: 0.7666 - lr: 5.0000e-04
Epoch 38/80
352/353 [============================>.] - ETA: 0s - loss: 0.6397 - accuracy: 0.7679
Epoch 38: val_loss improved from 0.65705 to 0.63274, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.6399 - accuracy: 0.7679 - val_loss: 0.6327 - val_accuracy: 0.7821 - lr: 5.0000e-04
Epoch 39/80
353/353 [==============================] - ETA: 0s - loss: 0.6335 - accuracy: 0.7684
Epoch 39: val_loss did not improve from 0.63274
353/353 [==============================] - 17s 48ms/step - loss: 0.6335 - accuracy: 0.7684 - val_loss: 0.6400 - val_accuracy: 0.7787 - lr: 5.0000e-04
Epoch 40/80
352/353 [============================>.] - ETA: 0s - loss: 0.6194 - accuracy: 0.7728
Epoch 40: val_loss did not improve from 0.63274
353/353 [==============================] - 17s 48ms/step - loss: 0.6194 - accuracy: 0.7727 - val_loss: 0.6500 - val_accuracy: 0.7710 - lr: 5.0000e-04
Epoch 41/80
353/353 [==============================] - ETA: 0s - loss: 0.6128 - accuracy: 0.7748Restoring model weights from the end of the best epoch: 38.

Epoch 41: val_loss improved from 0.63274 to 0.62615, saving model to best-model.h5
353/353 [==============================] - 17s 49ms/step - loss: 0.6128 - accuracy: 0.7748 - val_loss: 0.6261 - val_accuracy: 0.7789 - lr: 5.0000e-04
Epoch 41: early stopping
394/394 [==============================] - 3s 6ms/step - loss: 0.6214 - accuracy: 0.7894
Out[ ]:
[0.6213833093643188, 0.7894318699836731]
In [ ]:
model.save('augmented-model.h5', overwrite=True)

Final Model Results

In [ ]:
plot_model_history(history10, name="Final CNN Model Test")
Min validation loss: 0.590213418006897 
Max validation loss: 1.729331135749817 
Min validation acc: 0.33849820494651794 
Max validation acc: 0.835915744304657
In [ ]:
plot_model_history(history10, name="Final CNN Model")
Min validation loss: 0.5459099411964417 
Max validation loss: 1.7715320587158203 
Min validation acc: 0.3178386986255646 
Max validation acc: 0.851807713508606
In [ ]:
plot_model_history(history11, name="Final CNN Model with Data Augmentation")
Min validation loss: 0.6261454224586487 
Max validation loss: 1.9565800428390503 
Min validation acc: 0.1521652787923813 
Max validation acc: 0.7820818424224854

Predictions for Model without Data Augmentation

In [ ]:
# model = tf.keras.models.load_model('final-model.h5')
model = tf.keras.models.load_model('/content/drive/MyDrive/FER H5/final-model.h5') # saved the best model on google drive

data = []
predicted = np.argmax(model.predict(x_test), axis=1)
actual = np.argmax(y_test, axis=1)
validate = []
table = PrettyTable(['Predicted Emotion', 'Actual Emotion', 'Predicted Emotion Text', 'Actual Emotion Text', 'Validate'])

for i in range(50):
  validate.append('True' if predicted[i] == actual[i] else 'False')
  data.append([predicted[i], 
               actual[i], 
               decoded_emotions[predicted[i]], 
               decoded_emotions[actual[i]], 
               validate[i]]
              )
for record in data:
  table.add_row(record)
print(table)

true_predictions = validate.count('True')
print(f"\nNumber of true predictions: {true_predictions}/{len(validate)}")
+-------------------+----------------+------------------------+---------------------+----------+
| Predicted Emotion | Actual Emotion | Predicted Emotion Text | Actual Emotion Text | Validate |
+-------------------+----------------+------------------------+---------------------+----------+
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         0         |       0        |         Angry          |        Angry        |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         6         |       0        |        Neutral         |        Angry        |  False   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         0         |       0        |         Angry          |        Angry        |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         3         |       6        |         Happy          |       Neutral       |  False   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         4         |       2        |          Sad           |        Scared       |  False   |
|         0         |       0        |         Angry          |        Angry        |   True   |
|         4         |       6        |          Sad           |       Neutral       |  False   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
+-------------------+----------------+------------------------+---------------------+----------+

Number of true predictions: 46/50
In [ ]:
fig = plt.figure(figsize=(25, 15))
fig.suptitle("Predictions vs Truth", fontsize=20, weight='bold')
rows = 5
columns = 10

for i in range(rows * columns):
  fig.add_subplot(rows, columns, i+1)
  plt.grid(False)
  plt.imshow(np.squeeze(x_test[i]), cmap=plt.cm.gray)
  plt.xticks([])
  plt.yticks([])
  if decoded_emotions[predicted[i]] != decoded_emotions[actual[i]]:
    plt.title("Predicted: " + decoded_emotions[predicted[i]], color='r')
  else:
    plt.title("Predicted: " + decoded_emotions[predicted[i]], color='g')
  plt.xlabel("Actual: " + decoded_emotions[actual[i]], color='b')
save_figure("Predictions vs Truth", tight_layout=False)
plt.show()
Predictions vs Truth has been saved
In [ ]:
print(classification_report(actual, predicted, target_names=decoded_emotions.values()))
              precision    recall  f1-score   support

       Angry       0.80      0.84      0.82      1770
   Disgusted       0.98      1.00      0.99      1778
      Scared       0.83      0.77      0.80      1775
       Happy       0.86      0.83      0.84      1872
         Sad       0.73      0.70      0.72      1825
    Suprised       0.91      0.95      0.93      1755
     Neutral       0.75      0.79      0.77      1810

    accuracy                           0.84     12585
   macro avg       0.84      0.84      0.84     12585
weighted avg       0.84      0.84      0.84     12585

In [ ]:
confusion_matrix = tf.math.confusion_matrix(actual, predicted)
plt.figure(figsize=(10, 8))
sns.heatmap(confusion_matrix, annot=True, 
            cmap='Blues', fmt='d', 
            xticklabels=decoded_emotions.values(),
            yticklabels=decoded_emotions.values())
plt.xlabel('Predicted')
plt.ylabel('Actual')
save_figure("Confusion Matrix")
Confusion Matrix has been saved

Predictions for Model with Data Augmentation

In [ ]:
model = tf.keras.models.load_model('augmented-model.h5')

data = []
predicted = np.argmax(model.predict(x_test), axis=1)
actual = np.argmax(y_test, axis=1)
validate = []
table = PrettyTable(['Predicted Emotion', 'Actual Emotion', 'Predicted Emotion Text', 'Actual Emotion Text', 'Validate'])

for i in range(50):
  validate.append('True' if predicted[i] == actual[i] else 'False')
  data.append([predicted[i], 
               actual[i], 
               decoded_emotions[predicted[i]], 
               decoded_emotions[actual[i]], 
               validate[i]]
              )
for record in data:
  table.add_row(record)
print(table)

true_predictions = validate.count('True')
print(f"\nNumber of true predictions: {true_predictions}/{len(validate)}")
+-------------------+----------------+------------------------+---------------------+----------+
| Predicted Emotion | Actual Emotion | Predicted Emotion Text | Actual Emotion Text | Validate |
+-------------------+----------------+------------------------+---------------------+----------+
|         3         |       6        |         Happy          |       Neutral       |  False   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         0         |       5        |         Angry          |       Suprised      |  False   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         0         |       0        |         Angry          |        Angry        |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         6         |       3        |        Neutral         |        Happy        |  False   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         3         |       2        |         Happy          |        Scared       |  False   |
|         6         |       5        |        Neutral         |       Suprised      |  False   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         6         |       0        |        Neutral         |        Angry        |  False   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         3         |       6        |         Happy          |       Neutral       |  False   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         0         |       0        |         Angry          |        Angry        |   True   |
|         2         |       5        |         Scared         |       Suprised      |  False   |
|         2         |       4        |         Scared         |         Sad         |  False   |
|         3         |       6        |         Happy          |       Neutral       |  False   |
|         0         |       4        |         Angry          |         Sad         |  False   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         4         |       4        |          Sad           |         Sad         |   True   |
|         3         |       3        |         Happy          |        Happy        |   True   |
|         4         |       2        |          Sad           |        Scared       |  False   |
|         6         |       4        |        Neutral         |         Sad         |  False   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         0         |       0        |         Angry          |        Angry        |   True   |
|         0         |       6        |         Angry          |       Neutral       |  False   |
|         5         |       5        |        Suprised        |       Suprised      |   True   |
|         2         |       2        |         Scared         |        Scared       |   True   |
|         6         |       2        |        Neutral         |        Scared       |  False   |
|         6         |       6        |        Neutral         |       Neutral       |   True   |
|         1         |       1        |       Disgusted        |      Disgusted      |   True   |
|         5         |       2        |        Suprised        |        Scared       |  False   |
+-------------------+----------------+------------------------+---------------------+----------+

Number of true predictions: 34/50
In [ ]:
fig = plt.figure(figsize=(25, 15))
fig.suptitle("Predictions vs Truth", fontsize=20, weight='bold')
rows = 5
columns = 10

for i in range(rows * columns):
  fig.add_subplot(rows, columns, i+1)
  plt.grid(False)
  plt.imshow(np.squeeze(x_test[i]), cmap=plt.cm.gray)
  plt.xticks([])
  plt.yticks([])
  if decoded_emotions[predicted[i]] != decoded_emotions[actual[i]]:
    plt.title("Predicted: " + decoded_emotions[predicted[i]], color='r')
  else:
    plt.title("Predicted: " + decoded_emotions[predicted[i]], color='g')
  plt.xlabel("Actual: " + decoded_emotions[actual[i]], color='b')
save_figure("Predictions vs Truth", tight_layout=False)
plt.show()
Predictions vs Truth has been saved
In [ ]:
print(classification_report(actual, predicted, target_names=decoded_emotions.values()))
              precision    recall  f1-score   support

       Angry       0.74      0.78      0.76      1770
   Disgusted       0.99      1.00      0.99      1778
      Scared       0.75      0.64      0.69      1775
       Happy       0.87      0.83      0.85      1872
         Sad       0.70      0.59      0.64      1825
    Suprised       0.85      0.92      0.88      1755
     Neutral       0.64      0.77      0.70      1810

    accuracy                           0.79     12585
   macro avg       0.79      0.79      0.79     12585
weighted avg       0.79      0.79      0.79     12585

In [ ]:
confusion_matrix = tf.math.confusion_matrix(actual, predicted)
plt.figure(figsize=(10, 8))
sns.heatmap(confusion_matrix, annot=True, 
            cmap='Blues', fmt='d', 
            xticklabels=decoded_emotions.values(),
            yticklabels=decoded_emotions.values())
plt.xlabel('Predicted')
plt.ylabel('Actual')
save_figure("Confusion Matrix")
Confusion Matrix has been saved

Best Performing Model

Model Validation Loss Validation Accuracy True predictions on first 50 test images Best Model?
Final Model 0.5459 0.8518 46/50 Yes
Final Model with Data Augmentation 0.6261 0.7821 34/50 No

Saving the Model

In [ ]:
fer_to_json = model.to_json()  
with open("best-model.json", "w") as json_file:  
    json_file.write(fer_to_json)  

References

  • Chollet, F: "Deep Learning with Python", 2018
  • GĂ©ron, A: "Hands-On Machine Learning with Scikit-Learn, Keras & Tensor- Flow", 2019
  • Rahman, S: Artificial Intelligence: CW2 - Deep Learning for Computer Vision, 2022
  • Verma, R: fer2013, Kaggle, 2013, Accessed: 03-02-2022
  • Imbalanced Learn: "Random Over Sampler", 2022, URL: https://imbalanced-learn.org/stable/references/generated/imblearn.over_sampling.RandomOverSampler.html, Accessed: 23-02-2022
  • Brownlee, J: "How to Grid Search Hyperparameters for Deep Learning Models in Python With Keras", 2020, Accessed: 14-04-2022